rjhead 2.88.1 → 2.88.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/bin/jhead +0 -0
- data/rjhead.gemspec +4 -21
- metadata +6 -24
- data/ext/changes.txt +0 -351
- data/ext/exif.c +0 -1629
- data/ext/extconf.rb +0 -0
- data/ext/gpsinfo.c +0 -217
- data/ext/iptc.c +0 -205
- data/ext/jhead.1 +0 -409
- data/ext/jhead.c +0 -1697
- data/ext/jhead.h +0 -251
- data/ext/jhead.spec +0 -149
- data/ext/jpgfile.c +0 -738
- data/ext/make.bat +0 -1
- data/ext/makefile +0 -23
- data/ext/makefile-win32 +0 -27
- data/ext/makernote.c +0 -184
- data/ext/myglob.c +0 -305
- data/ext/paths.c +0 -140
- data/ext/readme.txt +0 -60
- data/ext/usage.html +0 -469
- data/setup.rake +0 -1
data/ext/extconf.rb
DELETED
File without changes
|
data/ext/gpsinfo.c
DELETED
@@ -1,217 +0,0 @@
|
|
1
|
-
//--------------------------------------------------------------------------
|
2
|
-
// Parsing of GPS info from exif header.
|
3
|
-
//
|
4
|
-
// Matthias Wandel, Dec 1999 - Dec 2002
|
5
|
-
//--------------------------------------------------------------------------
|
6
|
-
#include "jhead.h"
|
7
|
-
|
8
|
-
#define MAX_GPS_TAG 0x1e
|
9
|
-
|
10
|
-
|
11
|
-
#define TAG_GPS_LAT_REF 1
|
12
|
-
#define TAG_GPS_LAT 2
|
13
|
-
#define TAG_GPS_LONG_REF 3
|
14
|
-
#define TAG_GPS_LONG 4
|
15
|
-
#define TAG_GPS_ALT_REF 5
|
16
|
-
#define TAG_GPS_ALT 6
|
17
|
-
|
18
|
-
|
19
|
-
static const char * GpsTags[MAX_GPS_TAG+1]= {
|
20
|
-
"VersionID ",//0x00
|
21
|
-
"LatitudeRef ",//0x01
|
22
|
-
"Latitude ",//0x02
|
23
|
-
"LongitudeRef ",//0x03
|
24
|
-
"Longitude ",//0x04
|
25
|
-
"AltitudeRef ",//0x05
|
26
|
-
"Altitude ",//0x06
|
27
|
-
"TimeStamp ",//0x07
|
28
|
-
"Satellites ",//0x08
|
29
|
-
"Status ",//0x09
|
30
|
-
"MeasureMode ",//0x0A
|
31
|
-
"DOP ",//0x0B
|
32
|
-
"SpeedRef ",//0x0C
|
33
|
-
"Speed ",//0x0D
|
34
|
-
"TrackRef ",//0x0E
|
35
|
-
"Track ",//0x0F
|
36
|
-
"ImgDirectionRef ",//0x10
|
37
|
-
"ImgDirection ",//0x11
|
38
|
-
"MapDatum ",//0x12
|
39
|
-
"DestLatitudeRef ",//0x13
|
40
|
-
"DestLatitude ",//0x14
|
41
|
-
"DestLongitudeRef",//0x15
|
42
|
-
"DestLongitude ",//0x16
|
43
|
-
"DestBearingRef ",//0x17
|
44
|
-
"DestBearing ",//0x18
|
45
|
-
"DestDistanceRef ",//0x19
|
46
|
-
"DestDistance ",//0x1A
|
47
|
-
"ProcessingMethod",//0x1B
|
48
|
-
"AreaInformation ",//0x1C
|
49
|
-
"DateStamp ",//0x1D
|
50
|
-
"Differential ",//0x1E
|
51
|
-
};
|
52
|
-
|
53
|
-
//--------------------------------------------------------------------------
|
54
|
-
// Process GPS info directory
|
55
|
-
//--------------------------------------------------------------------------
|
56
|
-
void ProcessGpsInfo(unsigned char * DirStart, int ByteCountUnused, unsigned char * OffsetBase, unsigned ExifLength)
|
57
|
-
{
|
58
|
-
int de;
|
59
|
-
unsigned a;
|
60
|
-
int NumDirEntries;
|
61
|
-
|
62
|
-
NumDirEntries = Get16u(DirStart);
|
63
|
-
#define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
|
64
|
-
|
65
|
-
if (ShowTags){
|
66
|
-
printf("(dir has %d entries)\n",NumDirEntries);
|
67
|
-
}
|
68
|
-
|
69
|
-
ImageInfo.GpsInfoPresent = TRUE;
|
70
|
-
strcpy(ImageInfo.GpsLat, "? ?");
|
71
|
-
strcpy(ImageInfo.GpsLong, "? ?");
|
72
|
-
ImageInfo.GpsAlt[0] = 0;
|
73
|
-
|
74
|
-
for (de=0;de<NumDirEntries;de++){
|
75
|
-
unsigned Tag, Format, Components;
|
76
|
-
unsigned char * ValuePtr;
|
77
|
-
int ComponentSize;
|
78
|
-
unsigned ByteCount;
|
79
|
-
unsigned char * DirEntry;
|
80
|
-
DirEntry = DIR_ENTRY_ADDR(DirStart, de);
|
81
|
-
|
82
|
-
if (DirEntry+12 > OffsetBase+ExifLength){
|
83
|
-
ErrNonfatal("GPS info directory goes past end of exif",0,0);
|
84
|
-
return;
|
85
|
-
}
|
86
|
-
|
87
|
-
Tag = Get16u(DirEntry);
|
88
|
-
Format = Get16u(DirEntry+2);
|
89
|
-
Components = Get32u(DirEntry+4);
|
90
|
-
|
91
|
-
if ((Format-1) >= NUM_FORMATS) {
|
92
|
-
// (-1) catches illegal zero case as unsigned underflows to positive large.
|
93
|
-
ErrNonfatal("Illegal number format %d for Exif gps tag %04x", Format, Tag);
|
94
|
-
continue;
|
95
|
-
}
|
96
|
-
|
97
|
-
ComponentSize = BytesPerFormat[Format];
|
98
|
-
ByteCount = Components * ComponentSize;
|
99
|
-
|
100
|
-
if (ByteCount > 4){
|
101
|
-
unsigned OffsetVal;
|
102
|
-
OffsetVal = Get32u(DirEntry+8);
|
103
|
-
// If its bigger than 4 bytes, the dir entry contains an offset.
|
104
|
-
if (OffsetVal+ByteCount > ExifLength){
|
105
|
-
// Bogus pointer offset and / or bytecount value
|
106
|
-
ErrNonfatal("Illegal value pointer for Exif gps tag %04x", Tag,0);
|
107
|
-
continue;
|
108
|
-
}
|
109
|
-
ValuePtr = OffsetBase+OffsetVal;
|
110
|
-
}else{
|
111
|
-
// 4 bytes or less and value is in the dir entry itself
|
112
|
-
ValuePtr = DirEntry+8;
|
113
|
-
}
|
114
|
-
|
115
|
-
switch(Tag){
|
116
|
-
char FmtString[21];
|
117
|
-
char TempString[50];
|
118
|
-
double Values[3];
|
119
|
-
|
120
|
-
case TAG_GPS_LAT_REF:
|
121
|
-
ImageInfo.GpsLat[0] = ValuePtr[0];
|
122
|
-
break;
|
123
|
-
|
124
|
-
case TAG_GPS_LONG_REF:
|
125
|
-
ImageInfo.GpsLong[0] = ValuePtr[0];
|
126
|
-
break;
|
127
|
-
|
128
|
-
case TAG_GPS_LAT:
|
129
|
-
case TAG_GPS_LONG:
|
130
|
-
if (Format != FMT_URATIONAL){
|
131
|
-
ErrNonfatal("Inappropriate format (%d) for Exif GPS coordinates!", Format, 0);
|
132
|
-
}
|
133
|
-
strcpy(FmtString, "%0.0fd %0.0fm %0.0fs");
|
134
|
-
for (a=0;a<3;a++){
|
135
|
-
int den, digits;
|
136
|
-
|
137
|
-
den = Get32s(ValuePtr+4+a*ComponentSize);
|
138
|
-
digits = 0;
|
139
|
-
while (den > 1 && digits <= 6){
|
140
|
-
den = den / 10;
|
141
|
-
digits += 1;
|
142
|
-
}
|
143
|
-
if (digits > 6) digits = 6;
|
144
|
-
FmtString[1+a*7] = (char)('2'+digits+(digits ? 1 : 0));
|
145
|
-
FmtString[3+a*7] = (char)('0'+digits);
|
146
|
-
|
147
|
-
Values[a] = ConvertAnyFormat(ValuePtr+a*ComponentSize, Format);
|
148
|
-
}
|
149
|
-
|
150
|
-
sprintf(TempString, FmtString, Values[0], Values[1], Values[2]);
|
151
|
-
|
152
|
-
if (Tag == TAG_GPS_LAT){
|
153
|
-
strncpy(ImageInfo.GpsLat+2, TempString, 29);
|
154
|
-
}else{
|
155
|
-
strncpy(ImageInfo.GpsLong+2, TempString, 29);
|
156
|
-
}
|
157
|
-
break;
|
158
|
-
|
159
|
-
case TAG_GPS_ALT_REF:
|
160
|
-
ImageInfo.GpsAlt[0] = (char)(ValuePtr[0] ? '-' : ' ');
|
161
|
-
break;
|
162
|
-
|
163
|
-
case TAG_GPS_ALT:
|
164
|
-
sprintf(ImageInfo.GpsAlt + 1, "%.2fm",
|
165
|
-
ConvertAnyFormat(ValuePtr, Format));
|
166
|
-
break;
|
167
|
-
}
|
168
|
-
|
169
|
-
if (ShowTags){
|
170
|
-
// Show tag value.
|
171
|
-
if (Tag < MAX_GPS_TAG){
|
172
|
-
printf(" GPS%s =", GpsTags[Tag]);
|
173
|
-
}else{
|
174
|
-
// Show unknown tag
|
175
|
-
printf(" Illegal GPS tag %04x=", Tag);
|
176
|
-
}
|
177
|
-
|
178
|
-
switch(Format){
|
179
|
-
case FMT_UNDEFINED:
|
180
|
-
// Undefined is typically an ascii string.
|
181
|
-
|
182
|
-
case FMT_STRING:
|
183
|
-
// String arrays printed without function call (different from int arrays)
|
184
|
-
{
|
185
|
-
printf("\"");
|
186
|
-
for (a=0;a<ByteCount;a++){
|
187
|
-
int ZeroSkipped = 0;
|
188
|
-
if (ValuePtr[a] >= 32){
|
189
|
-
if (ZeroSkipped){
|
190
|
-
printf("?");
|
191
|
-
ZeroSkipped = 0;
|
192
|
-
}
|
193
|
-
putchar(ValuePtr[a]);
|
194
|
-
}else{
|
195
|
-
if (ValuePtr[a] == 0){
|
196
|
-
ZeroSkipped = 1;
|
197
|
-
}
|
198
|
-
}
|
199
|
-
}
|
200
|
-
printf("\"\n");
|
201
|
-
}
|
202
|
-
break;
|
203
|
-
|
204
|
-
default:
|
205
|
-
// Handle arrays of numbers later (will there ever be?)
|
206
|
-
for (a=0;;){
|
207
|
-
PrintFormatNumber(ValuePtr+a*ComponentSize, Format, ByteCount);
|
208
|
-
if (++a >= Components) break;
|
209
|
-
printf(", ");
|
210
|
-
}
|
211
|
-
printf("\n");
|
212
|
-
}
|
213
|
-
}
|
214
|
-
}
|
215
|
-
}
|
216
|
-
|
217
|
-
|
data/ext/iptc.c
DELETED
@@ -1,205 +0,0 @@
|
|
1
|
-
//--------------------------------------------------------------------------
|
2
|
-
// Process IPTC data and XMP data.
|
3
|
-
//--------------------------------------------------------------------------
|
4
|
-
#include "jhead.h"
|
5
|
-
|
6
|
-
// IPTC entry types known to Jhead (there's many more defined)
|
7
|
-
#define IPTC_RECORD_VERSION 0x00
|
8
|
-
#define IPTC_SUPLEMENTAL_CATEGORIES 0x14
|
9
|
-
#define IPTC_KEYWORDS 0x19
|
10
|
-
#define IPTC_CAPTION 0x78
|
11
|
-
#define IPTC_AUTHOR 0x7A
|
12
|
-
#define IPTC_HEADLINE 0x69
|
13
|
-
#define IPTC_SPECIAL_INSTRUCTIONS 0x28
|
14
|
-
#define IPTC_CATEGORY 0x0F
|
15
|
-
#define IPTC_BYLINE 0x50
|
16
|
-
#define IPTC_BYLINE_TITLE 0x55
|
17
|
-
#define IPTC_CREDIT 0x6E
|
18
|
-
#define IPTC_SOURCE 0x73
|
19
|
-
#define IPTC_COPYRIGHT_NOTICE 0x74
|
20
|
-
#define IPTC_OBJECT_NAME 0x05
|
21
|
-
#define IPTC_CITY 0x5A
|
22
|
-
#define IPTC_STATE 0x5F
|
23
|
-
#define IPTC_COUNTRY 0x65
|
24
|
-
#define IPTC_TRANSMISSION_REFERENCE 0x67
|
25
|
-
#define IPTC_DATE 0x37
|
26
|
-
#define IPTC_COPYRIGHT 0x0A
|
27
|
-
#define IPTC_COUNTRY_CODE 0x64
|
28
|
-
#define IPTC_REFERENCE_SERVICE 0x2D
|
29
|
-
#define IPTC_TIME_CREATED 0x3C
|
30
|
-
#define IPTC_SUB_LOCATION 0x5C
|
31
|
-
#define IPTC_IMAGE_TYPE 0x82
|
32
|
-
|
33
|
-
//--------------------------------------------------------------------------
|
34
|
-
// Process and display IPTC marker.
|
35
|
-
//
|
36
|
-
// IPTC block consists of:
|
37
|
-
// - Marker: 1 byte (0xED)
|
38
|
-
// - Block length: 2 bytes
|
39
|
-
// - IPTC Signature: 14 bytes ("Photoshop 3.0\0")
|
40
|
-
// - 8BIM Signature 4 bytes ("8BIM")
|
41
|
-
// - IPTC Block start 2 bytes (0x04, 0x04)
|
42
|
-
// - IPTC Header length 1 byte
|
43
|
-
// - IPTC header Header is padded to even length, counting the length byte
|
44
|
-
// - Length 4 bytes
|
45
|
-
// - IPTC Data which consists of a number of entries, each of which has the following format:
|
46
|
-
// - Signature 2 bytes (0x1C02)
|
47
|
-
// - Entry type 1 byte (for defined entry types, see #defines above)
|
48
|
-
// - entry length 2 bytes
|
49
|
-
// - entry data 'entry length' bytes
|
50
|
-
//
|
51
|
-
//--------------------------------------------------------------------------
|
52
|
-
void show_IPTC (unsigned char* Data, unsigned int itemlen)
|
53
|
-
{
|
54
|
-
const char IptcSig1[] = "Photoshop 3.0";
|
55
|
-
const char IptcSig2[] = "8BIM";
|
56
|
-
const char IptcSig3[] = {0x04, 0x04};
|
57
|
-
|
58
|
-
unsigned char * pos = Data + sizeof(short); // position data pointer after length field
|
59
|
-
unsigned char * maxpos = Data+itemlen;
|
60
|
-
char headerLen = 0;
|
61
|
-
|
62
|
-
if (itemlen < 25) goto corrupt;
|
63
|
-
|
64
|
-
// Check IPTC signatures
|
65
|
-
if (memcmp(pos, IptcSig1, sizeof(IptcSig1)-1) != 0) goto badsig;
|
66
|
-
pos += sizeof(IptcSig1); // move data pointer to the next field
|
67
|
-
|
68
|
-
if (memcmp(pos, IptcSig2, sizeof(IptcSig2)-1) != 0) goto badsig;
|
69
|
-
pos += sizeof(IptcSig2)-1; // move data pointer to the next field
|
70
|
-
|
71
|
-
if (memcmp(pos, IptcSig3, sizeof(IptcSig3)) != 0){
|
72
|
-
badsig:
|
73
|
-
if (ShowTags){
|
74
|
-
ErrNonfatal("IPTC type signature mismatch\n",0,0);
|
75
|
-
}
|
76
|
-
return;
|
77
|
-
}
|
78
|
-
pos += sizeof(IptcSig3); // move data pointer to the next field
|
79
|
-
|
80
|
-
if (pos >= maxpos) goto corrupt;
|
81
|
-
|
82
|
-
// IPTC section found
|
83
|
-
|
84
|
-
// Skip header
|
85
|
-
headerLen = *pos++; // get header length and move data pointer to the next field
|
86
|
-
pos += headerLen + 1 - (headerLen % 2); // move data pointer to the next field (Header is padded to even length, counting the length byte)
|
87
|
-
|
88
|
-
if (pos+4 >= maxpos) goto corrupt;
|
89
|
-
|
90
|
-
// Get length (from motorola format)
|
91
|
-
//length = (*pos << 24) | (*(pos+1) << 16) | (*(pos+2) << 8) | *(pos+3);
|
92
|
-
|
93
|
-
pos += 4; // move data pointer to the next field
|
94
|
-
|
95
|
-
printf("======= IPTC data: =======\n");
|
96
|
-
|
97
|
-
// Now read IPTC data
|
98
|
-
while (pos < (Data + itemlen-5)) {
|
99
|
-
short signature;
|
100
|
-
unsigned char type = 0;
|
101
|
-
short length = 0;
|
102
|
-
char * description = NULL;
|
103
|
-
|
104
|
-
if (pos+5 > maxpos) goto corrupt;
|
105
|
-
|
106
|
-
signature = (*pos << 8) + (*(pos+1));
|
107
|
-
pos += 2;
|
108
|
-
|
109
|
-
if (signature != 0x1C02){
|
110
|
-
break;
|
111
|
-
}
|
112
|
-
|
113
|
-
type = *pos++;
|
114
|
-
length = (*pos << 8) + (*(pos+1));
|
115
|
-
pos += 2; // Skip tag length
|
116
|
-
|
117
|
-
if (pos+length > maxpos) goto corrupt;
|
118
|
-
// Process tag here
|
119
|
-
switch (type) {
|
120
|
-
case IPTC_RECORD_VERSION:
|
121
|
-
printf("Record vers. : %d\n", (*pos << 8) + (*(pos+1)));
|
122
|
-
break;
|
123
|
-
|
124
|
-
case IPTC_SUPLEMENTAL_CATEGORIES: description = "SuplementalCategories"; break;
|
125
|
-
case IPTC_KEYWORDS: description = "Keywords"; break;
|
126
|
-
case IPTC_CAPTION: description = "Caption"; break;
|
127
|
-
case IPTC_AUTHOR: description = "Author"; break;
|
128
|
-
case IPTC_HEADLINE: description = "Headline"; break;
|
129
|
-
case IPTC_SPECIAL_INSTRUCTIONS: description = "Spec. Instr."; break;
|
130
|
-
case IPTC_CATEGORY: description = "Category"; break;
|
131
|
-
case IPTC_BYLINE: description = "Byline"; break;
|
132
|
-
case IPTC_BYLINE_TITLE: description = "Byline Title"; break;
|
133
|
-
case IPTC_CREDIT: description = "Credit"; break;
|
134
|
-
case IPTC_SOURCE: description = "Source"; break;
|
135
|
-
case IPTC_COPYRIGHT_NOTICE: description = "(C)Notice"; break;
|
136
|
-
case IPTC_OBJECT_NAME: description = "Object Name"; break;
|
137
|
-
case IPTC_CITY: description = "City"; break;
|
138
|
-
case IPTC_STATE: description = "State"; break;
|
139
|
-
case IPTC_COUNTRY: description = "Country"; break;
|
140
|
-
case IPTC_TRANSMISSION_REFERENCE: description = "OriginalTransmissionReference"; break;
|
141
|
-
case IPTC_DATE: description = "DateCreated"; break;
|
142
|
-
case IPTC_COPYRIGHT: description = "(C)Flag"; break;
|
143
|
-
case IPTC_REFERENCE_SERVICE: description = "Country Code"; break;
|
144
|
-
case IPTC_COUNTRY_CODE: description = "Ref. Service"; break;
|
145
|
-
case IPTC_TIME_CREATED: description = "Time Created"; break;
|
146
|
-
case IPTC_SUB_LOCATION: description = "Sub Location"; break;
|
147
|
-
case IPTC_IMAGE_TYPE: description = "Image type"; break;
|
148
|
-
|
149
|
-
default:
|
150
|
-
if (ShowTags){
|
151
|
-
printf("Unrecognised IPTC tag: %d\n", type );
|
152
|
-
}
|
153
|
-
break;
|
154
|
-
}
|
155
|
-
if (description != NULL) {
|
156
|
-
char TempBuf[32];
|
157
|
-
memset(TempBuf, 0, sizeof(TempBuf));
|
158
|
-
memset(TempBuf, ' ', 14);
|
159
|
-
memcpy(TempBuf, description, strlen(description));
|
160
|
-
strcat(TempBuf, ":");
|
161
|
-
printf("%s %*.*s\n", TempBuf, length, length, pos);
|
162
|
-
}
|
163
|
-
pos += length;
|
164
|
-
}
|
165
|
-
return;
|
166
|
-
corrupt:
|
167
|
-
ErrNonfatal("Pointer corruption in IPTC\n",0,0);
|
168
|
-
}
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
//--------------------------------------------------------------------------
|
173
|
-
// Dump contents of XMP section
|
174
|
-
//--------------------------------------------------------------------------
|
175
|
-
void ShowXmp(Section_t XmpSection)
|
176
|
-
{
|
177
|
-
unsigned char * Data;
|
178
|
-
char OutLine[101];
|
179
|
-
int OutLineChars;
|
180
|
-
int NonBlank;
|
181
|
-
unsigned a;
|
182
|
-
NonBlank = 0;
|
183
|
-
Data = XmpSection.Data;
|
184
|
-
OutLineChars = 0;
|
185
|
-
|
186
|
-
|
187
|
-
for (a=0;a<XmpSection.Size;a++){
|
188
|
-
if (Data[a] >= 32 && Data[a] < 128){
|
189
|
-
OutLine[OutLineChars++] = Data[a];
|
190
|
-
if (Data[a] != ' ') NonBlank |= 1;
|
191
|
-
}else{
|
192
|
-
if (Data[a] != '\n'){
|
193
|
-
OutLine[OutLineChars++] = '?';
|
194
|
-
}
|
195
|
-
}
|
196
|
-
if (Data[a] == '\n' || OutLineChars >= 100){
|
197
|
-
OutLine[OutLineChars] = 0;
|
198
|
-
if (NonBlank){
|
199
|
-
puts(OutLine);
|
200
|
-
}
|
201
|
-
NonBlank = (NonBlank & 1) << 1;
|
202
|
-
OutLineChars = 0;
|
203
|
-
}
|
204
|
-
}
|
205
|
-
}
|
data/ext/jhead.1
DELETED
@@ -1,409 +0,0 @@
|
|
1
|
-
.TH JHEAD 1 "06 Nov 2009" "jhead 2.88"
|
2
|
-
.SH NAME
|
3
|
-
jhead \- Digicam JPEG Exif header manipulation tool
|
4
|
-
.SH SYNOPSIS
|
5
|
-
.B jhead
|
6
|
-
[
|
7
|
-
.I options
|
8
|
-
]
|
9
|
-
[
|
10
|
-
.I file\.\.\.
|
11
|
-
]
|
12
|
-
|
13
|
-
.LP
|
14
|
-
.SH DESCRIPTION
|
15
|
-
.LP
|
16
|
-
.B jhead
|
17
|
-
is used to display and manipulate data contained in the Exif header of JPEG
|
18
|
-
images from digital cameras. By default, jhead displays the more useful
|
19
|
-
camera settings from the file in a user-friendly format.
|
20
|
-
.PP
|
21
|
-
.B jhead
|
22
|
-
can also be used to manipulate some aspects of the image relating to JPEG and
|
23
|
-
Exif headers, such as changing the internal timestamps, removing the thumbnail,
|
24
|
-
or transferring Exif headers back into edited images after graphical editors
|
25
|
-
deleted the Exif header.
|
26
|
-
.B jhead
|
27
|
-
can also be used to launch other programs, similar in style to the UNIX
|
28
|
-
.B find
|
29
|
-
command, but much simpler.
|
30
|
-
|
31
|
-
|
32
|
-
.SH GENERAL METADATA OPTIONS
|
33
|
-
.TP
|
34
|
-
.BI \-\^te \ file
|
35
|
-
Transplant Exif header from a JPEG (with Exif header) in
|
36
|
-
.I file
|
37
|
-
into the image that is manipulated. This option is
|
38
|
-
useful if you like to edit the photos but still want the Exif header on your photos.
|
39
|
-
As most photo editing programs will wipe out the Exif header, this option can be used
|
40
|
-
to re-copy them back from original copies after editing the photos.
|
41
|
-
|
42
|
-
|
43
|
-
This feature has an interesting 'relative path' option for specifying the
|
44
|
-
thumbnail name. Whenever the <name> contains the characters '&i',
|
45
|
-
will substitute the original filename for this name. This allows creating a
|
46
|
-
jhead 'relative name' when doing a whole batch of files. For example, the
|
47
|
-
incantation:
|
48
|
-
|
49
|
-
.B jhead -te "originals\&i" *.jpg
|
50
|
-
|
51
|
-
would transfer the exif header for each .jpg file in the originals directory by
|
52
|
-
the same name, Both Win32 and most Unix shells treat the '&' character in a
|
53
|
-
special way, so you have to put quotes around that command line option for
|
54
|
-
the '&' to even be passed to the program.
|
55
|
-
|
56
|
-
.TP
|
57
|
-
.B \-dc
|
58
|
-
Delete comment field from the JPEG header. Note that the comment
|
59
|
-
is not part of the Exif header.
|
60
|
-
.TP
|
61
|
-
.B \-de
|
62
|
-
Delete the Exif header entirely. Leaves other metadata sections intact.
|
63
|
-
.TP
|
64
|
-
.B \-di
|
65
|
-
Delete the IPTC section, if present. Leaves other metadata sections intact.
|
66
|
-
.TP
|
67
|
-
.B \-dx
|
68
|
-
Delete the XMP section, if present. Leaves other metadata sections intact.
|
69
|
-
.TP
|
70
|
-
.B \-du
|
71
|
-
Delete sections of jpeg that are not Exif, not comment, and otherwise not
|
72
|
-
contributing to the image either - such as data that photoshop might leave in the image.
|
73
|
-
.TP
|
74
|
-
.B \-purejpg
|
75
|
-
Delete all JPEG sections that aren't necessary for rendering the image. Strips any
|
76
|
-
metadata that various applications may have left in the image. A combination of
|
77
|
-
the -de -dc and -du options.
|
78
|
-
.TP
|
79
|
-
.B \-mkexif
|
80
|
-
Creates minimal exif header. Exif header contains date/time, and empty thumbnail
|
81
|
-
fields only. Date/time set to file time by default. Use with -rgt option if you
|
82
|
-
want the exif header to contain a thumbnail. Note that exif header creation is
|
83
|
-
very limited at this time, and no other fields can be added to the exif header
|
84
|
-
this way.
|
85
|
-
.TP
|
86
|
-
.B \-ce
|
87
|
-
Edit the JPEG header comment field (note, this comment field is outside the Exif structure
|
88
|
-
and can be part of Exif and non Exif style JPEG images).
|
89
|
-
|
90
|
-
A temporary file containing the comment is created and a text editor is launched to edit
|
91
|
-
the file. The editor is specified in the EDITOR environment variable. If none is specified
|
92
|
-
notepad or vi are used under Windows and Unix respectively. After the editor exits,
|
93
|
-
the data is transferred back into the image, and the temporary file deleted.
|
94
|
-
.TP
|
95
|
-
.BI \-\^cs \ file
|
96
|
-
Save comment section to a
|
97
|
-
.I file
|
98
|
-
.TP
|
99
|
-
.BI \-\^ci \ file
|
100
|
-
Replace comment with text from
|
101
|
-
.I file
|
102
|
-
.TP
|
103
|
-
.BI \-\^cl \ string
|
104
|
-
Replace comment with specified string from command line
|
105
|
-
.IR file
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
.SH DATE / TIME MANIPULATION OPTIONS
|
110
|
-
|
111
|
-
.TP
|
112
|
-
.B \-ft
|
113
|
-
Sets the file's system time stamp to what is stored in the Exif header.
|
114
|
-
.TP
|
115
|
-
.B \-dsft
|
116
|
-
Sets the Exif timestamp to the file's timestamp. Requires an Exif header to
|
117
|
-
pre-exist. Use -mkexif option to create one if needed.
|
118
|
-
.TP
|
119
|
-
.BI \-\^n [format_string]
|
120
|
-
This option causes files to be renamed and/ or mmoved using the date information from the Exif header
|
121
|
-
"DateTimeOriginal" field.
|
122
|
-
If the file is not an Exif file, or the DateTimeOriginal does not contain a valid value,
|
123
|
-
the file date is used.
|
124
|
-
Renaming is by default restricted to files whose names consist largely of digits.
|
125
|
-
This effectively restricts renaming to files that have not already been manually renamed, as
|
126
|
-
the default sequential names from digital cameras consist largely of digits.
|
127
|
-
Use the
|
128
|
-
.B -nf
|
129
|
-
option to force renaming of all files.
|
130
|
-
If the new name contains a '/', this will be interpreted as a new path, and the file will be
|
131
|
-
moved accordingly.
|
132
|
-
|
133
|
-
|
134
|
-
If the
|
135
|
-
.I format_string
|
136
|
-
is omitted, the file will be renamed to MMDD-HHMMSS. Note that
|
137
|
-
this scheme doesn't include the year (I never have photos from different years together anyway).
|
138
|
-
|
139
|
-
If a
|
140
|
-
.I format_string
|
141
|
-
is provided, it will be passed to the strftime function as the format string.
|
142
|
-
In addition, if the format string contains '%f', this will
|
143
|
-
substitute the original name of the file (minus extension). '%i' will substitute a sequence
|
144
|
-
number. Leading zeros can be specified like with printf - i.e. '%04i' pads the number to 4
|
145
|
-
digits using leading zeros.
|
146
|
-
|
147
|
-
If the name includes '/', this is interpreted as a new path for the file.
|
148
|
-
If the new path does not exist, the path will be created.
|
149
|
-
|
150
|
-
If the target name already exists, the name will be appended with "a", "b", "c", etc,
|
151
|
-
unless the name ends with a letter, in which case it will be appended with "0", "1", "2", etc.
|
152
|
-
|
153
|
-
This feature is especially useful if more than one digital camera was used to take pictures
|
154
|
-
of an event. By renaming them to a scheme according to date, they will automatically
|
155
|
-
appear in order of taking in most directory listings and image browsers. Alternatively,
|
156
|
-
if your image browser supports listing by file time, you can use the -ft option to set
|
157
|
-
the file time to the time the photo was taken.
|
158
|
-
|
159
|
-
Some of the more useful arguments for strftime are:
|
160
|
-
|
161
|
-
.BR %H \ Hour\ in\ 24-hour\ format\ (00\ -\ 23)
|
162
|
-
.br
|
163
|
-
.BR %j \ Day\ of\ year\ as\ decimal\ number\ (001\ -\ 366)
|
164
|
-
.br
|
165
|
-
.BR %m \ Month\ as\ decimal\ number\ (01\ -\ 12)
|
166
|
-
.br
|
167
|
-
.BR %M \ Minute\ as\ decimal\ number\ (00\ -\ 59)
|
168
|
-
.br
|
169
|
-
.BR %S \ Second\ as\ decimal\ number\ (00\ -\ 59)
|
170
|
-
.br
|
171
|
-
.BR %w \ Weekday\ as\ decimal\ number\ (0\ -\ 6;\ Sunday\ is\ 0)
|
172
|
-
.br
|
173
|
-
.BR %y \ Year\ without\ century,\ as\ decimal\ number\ (00\ -\ 99)
|
174
|
-
.br
|
175
|
-
.BR %Y \ Year\ with\ century,\ as\ decimal\ number
|
176
|
-
|
177
|
-
Example:
|
178
|
-
|
179
|
-
.B jhead -n%Y%m%d-%H%M%S *.jpg
|
180
|
-
This will rename files matched by *.jpg in the format YYYYMMDD-HHMMSS
|
181
|
-
|
182
|
-
For a full listing of strftime arguments, look up the strftime in them man pages.
|
183
|
-
Note that some arguments
|
184
|
-
to the strftime function (not listed here) produce strings with characters such as ':' that
|
185
|
-
may not be valid as part of a filename on some systems.
|
186
|
-
|
187
|
-
.TP
|
188
|
-
.B \-nf
|
189
|
-
Same as '-n' but renames files regardless of original file name.
|
190
|
-
|
191
|
-
|
192
|
-
.TP
|
193
|
-
.B \-ta<+|-><timediff>
|
194
|
-
Adjust time stored in the Exif header by h:mm backwards or forwards. Useful when having
|
195
|
-
taken pictures with the wrong time set on the camera, such as after travelling across
|
196
|
-
time zones, or when daylight savings time has changed.
|
197
|
-
|
198
|
-
This option changes all Date/time fields in the exif header, including "DateTimeOriginal" (tag 0x9003)
|
199
|
-
and "DateTimeDigitized" (tag 0x9004).
|
200
|
-
.TP
|
201
|
-
.B \-da<newdate>-<olddate>
|
202
|
-
|
203
|
-
Works like -ta, but for specifying large date offsets, to be used when fixing dates from
|
204
|
-
cameras where the date was set incorrectly, such as having date and time reset by battery
|
205
|
-
removal on some cameras
|
206
|
-
|
207
|
-
Because different months and years have different numbers of days in them, a simple offset
|
208
|
-
for months, days, years would lead to unexpected results at times. The time offset is
|
209
|
-
thus specified as a difference between two dates, so that jhead can figure out exactly
|
210
|
-
how many days the timestamp needs to be adjusted by, including leap years and daylight
|
211
|
-
savings time changes.
|
212
|
-
The dates are specified as yyyy:mm:dd. For sub-day adjustments, a time of day can also
|
213
|
-
be included, by specifying yyyy:nn:dd/hh:mm or yyyy:mm:dd/hh:mm:ss
|
214
|
-
|
215
|
-
Examples:
|
216
|
-
|
217
|
-
Year on camera was set to 2005 instead of 2004 for pictures taken in April
|
218
|
-
.br
|
219
|
-
jhead -da2004:03:01-2005:03:01
|
220
|
-
|
221
|
-
Default camera date is 2002:01:01, and date was reset on 2005:05:29 at 11:21 am
|
222
|
-
.br
|
223
|
-
jhead -da2005:05:29/11:21-2002:01:01
|
224
|
-
.TP
|
225
|
-
.B \-ts
|
226
|
-
Sets the time stored in the Exif header to what is specified on the command line.
|
227
|
-
Time must be specified as:
|
228
|
-
.I yyyy:mm:dd-hh:mm:ss
|
229
|
-
.TP
|
230
|
-
.B \-ds
|
231
|
-
Sets the date stored in the Exif header to what is specified on the command line.
|
232
|
-
Can be used to set date, just year and month, or just year.
|
233
|
-
Date is specified as:
|
234
|
-
.I yyyy:mm:dd, yyyy:mm, or yyyy
|
235
|
-
|
236
|
-
|
237
|
-
.SH THUMBNAIL MANIPULATION OPTIONS
|
238
|
-
|
239
|
-
.TP
|
240
|
-
.B \-dt
|
241
|
-
Delete thumbnails from the Exif header, but leave the
|
242
|
-
interesting parts intact. This option truncates the thumbnail from the Exif header, provided
|
243
|
-
that the thumbnail is the last part of the Exif header (which so far as I know is always the case).
|
244
|
-
Exif headers have a built-in thumbnail, which typically
|
245
|
-
occupies around 10k of space. This thumbnail is used by digital cameras. Windows XP may also
|
246
|
-
use this thumbnail if present (but it doesn't need it). The
|
247
|
-
thumbnails are too small to use even full screen on the digicam's LCD.
|
248
|
-
I have not encountered any adverse side effects of deleting the thumbnails, even from the
|
249
|
-
software provided with my old Olympus digicam. Use with caution.
|
250
|
-
|
251
|
-
.TP
|
252
|
-
.BI \-\^st \ file
|
253
|
-
Save the integral thumbnail to
|
254
|
-
.I file
|
255
|
-
The thumbnail lives
|
256
|
-
inside the Exif header, and is a very low-res JPEG image. Note that making
|
257
|
-
any changes to a photo, except for with some programs, generally wipes out the Exif header
|
258
|
-
and with it the thumbnail.
|
259
|
-
|
260
|
-
The thumbnail is too low res to really use for very much.
|
261
|
-
|
262
|
-
This feature has an interesting 'relative path' option for specifying the thumbnail name.
|
263
|
-
Whenever the name for
|
264
|
-
.I file
|
265
|
-
contains the characters '&i',
|
266
|
-
.B jhead
|
267
|
-
will substitute the original
|
268
|
-
filename for this name. This allows creating a 'relative name' when doing a whole
|
269
|
-
batch of files. For example, the incantation:
|
270
|
-
|
271
|
-
.B jhead -st "thumbnails/&i" *.jpg
|
272
|
-
|
273
|
-
would create a thumbnail for each .jpg file in the thumbnails directory by the same name,
|
274
|
-
(provided that the thumbnails directory exists, of course).
|
275
|
-
Both Win32 and UNIX shells treat the '&'character in a special way, so you have to
|
276
|
-
put quotes around that command line option for the '&' to even be passed to the program.
|
277
|
-
|
278
|
-
If a '-' is specified for the output file, the thumbnail is sent to stdout. (UNIX build only)
|
279
|
-
|
280
|
-
.TP
|
281
|
-
.B \-rt
|
282
|
-
Replace thumbnails from the Exif header.
|
283
|
-
This only works if the exif header already contains a thumbnail, and the thumbnail is at the
|
284
|
-
end of the header (both always the case if the photo came from a digital camera)
|
285
|
-
.TP
|
286
|
-
.BI \-\^rgt \ size
|
287
|
-
Regenerate exif thumbnail. 'size' specifies maximum height or width of thumbnail.
|
288
|
-
Relies on 'mogrify' program (from ImageMagick) to regenerate the thumbnail.
|
289
|
-
This only works if the image already contains a thumbnail.
|
290
|
-
|
291
|
-
.SH ROTATION OPTIONS
|
292
|
-
.TP
|
293
|
-
.B \-autorot
|
294
|
-
Using the 'Orientation' tag of the Exif header, rotate the image so that it is upright.
|
295
|
-
The program
|
296
|
-
.B jpegtran
|
297
|
-
is used to perform the rotation. This program is present in most
|
298
|
-
Linux distributions. For windows, you need to get a copy of it. After rotation, the
|
299
|
-
orientation tag of the Exif header is set to '1' (normal orientation). The thumbnail
|
300
|
-
is also rotated. Other fields of the Exif header, including
|
301
|
-
dimensions are untouched, but the JPEG height/width are adjusted.
|
302
|
-
This feature is especially useful with newer Canon cameras, that set the orientation
|
303
|
-
tag automatically using a gravity sensor.
|
304
|
-
.TP
|
305
|
-
.B \-norot
|
306
|
-
Clears the rotation field in the Exif header without altering the image. Useful if
|
307
|
-
the images were previously rotated without clearing the Exif rotation tag, as some
|
308
|
-
image browsers will auto rotate images when the rotation tag is set.
|
309
|
-
Sometimes, thumbnails and rotation tags can get very out of sync from manipulation
|
310
|
-
with various tools. To reset it all use -norot with -rgt to clear this out.
|
311
|
-
|
312
|
-
.SH OUTPUT VERBOSITY CONTROL
|
313
|
-
.TP
|
314
|
-
.B \-h
|
315
|
-
Displays summary of command line options.
|
316
|
-
.TP
|
317
|
-
.B \-v
|
318
|
-
Makes the program even more verbose than it already is. Like DOS programs, and unlike
|
319
|
-
UNIX programs, Jhead gives feedback as to what it is doing, even when nothing goes wrong.
|
320
|
-
Windows user that I am, when something doesn't give me feedback for 20 seconds, I assume
|
321
|
-
its crashed.
|
322
|
-
.TP
|
323
|
-
.B \-q
|
324
|
-
No output on success, more like Unix programs.
|
325
|
-
.TP
|
326
|
-
.B \-V
|
327
|
-
Print version info and compilation date.
|
328
|
-
.B \-exifmap
|
329
|
-
Show a map of the bytes in the exif header. Useful when analyzing strange exif headers,
|
330
|
-
not of much use to non software developers.
|
331
|
-
.TP
|
332
|
-
.B \-se
|
333
|
-
Suppress error messages relating to corrupt Exif header structure.
|
334
|
-
.TP
|
335
|
-
.B \-c
|
336
|
-
Concise output. This causes picture info to be summarized on one line instead of several.
|
337
|
-
Useful for grep-ing through images, as well as importing into spread sheets (data is space
|
338
|
-
delimited with quotes as text qualifier).
|
339
|
-
|
340
|
-
.SH FILE MATCHING OPTIONS
|
341
|
-
.TP
|
342
|
-
.B \-model
|
343
|
-
Restricts processing of files to those whose camera model, as indicated by the Exif image
|
344
|
-
information, contains the substring specified in the argument after '-model'.
|
345
|
-
For example, the following command will list only images that are from an S100 camera:
|
346
|
-
|
347
|
-
.B jhead -model S100 *.jpg
|
348
|
-
|
349
|
-
.B jhead -model S100 *.jpg
|
350
|
-
|
351
|
-
I use this option to restrict my JPEG recompensing to those images that came from my
|
352
|
-
Canon S100 digicam, (see the -cmd option).
|
353
|
-
.TP
|
354
|
-
.B \-exonly
|
355
|
-
Skip all files that don't have an Exif header. Photos straight from a digital camera
|
356
|
-
have an Exif header, whereas many photo manipulation tools discard the Exif header.
|
357
|
-
.TP
|
358
|
-
.B \-cmd
|
359
|
-
Executes the specified command on each JPEG file to be processed.
|
360
|
-
|
361
|
-
The Exif section of each file is read before running the command, and reinserted
|
362
|
-
after the command finishes.
|
363
|
-
|
364
|
-
The specified command invoked separately for each JPEG that is processed, even if
|
365
|
-
multiple files are specified (explicitly or by wild card).
|
366
|
-
|
367
|
-
Example use:
|
368
|
-
|
369
|
-
Having a whole directory of photos from my S100, I run the following commands:
|
370
|
-
|
371
|
-
.B jhead -cmd "mogrify -quality 80 &i" -model S100 -r *.jpg
|
372
|
-
.br
|
373
|
-
.B jhead -cmd "jpegtran -progressive &i > &o" -r *.jpg
|
374
|
-
|
375
|
-
The first command mogrifies all JPEGs in the tree that indicate that they are from a
|
376
|
-
Canon S100 in their Exif header to 80% quality at the same resolution. This is a 'lossy'
|
377
|
-
process, so I only run it on files that are from the Canon, and only run it once.
|
378
|
-
The next command then takes a JPEGs and converts them to progressive JPEGs. The result
|
379
|
-
is the same images, with no discernible differences, stored in half the space. This
|
380
|
-
produces substantial savings on some cameras.
|
381
|
-
|
382
|
-
.SH SEE ALSO
|
383
|
-
.BR jpegtran (1),
|
384
|
-
.BR mogrify (1),
|
385
|
-
.BR rdjpgcom (1),
|
386
|
-
.BR wrjpgcom (1)
|
387
|
-
.SH AUTHOR
|
388
|
-
Matthias Wandel
|
389
|
-
.SH BUGS
|
390
|
-
After jhead runs a program to rotate or resize an image, the image dimensions and thumbnail
|
391
|
-
in the Exif header are not adjusted.
|
392
|
-
.PP
|
393
|
-
Modifying of Exif header data is very limited, as Jhead internally only has a read only
|
394
|
-
implementation of the file system contained in the Exif header. For example, there is no way
|
395
|
-
to replace the thumbnail or edit the Exif comment in the Exif header. There is also no way
|
396
|
-
to create minimal exif headers.
|
397
|
-
.PP
|
398
|
-
Some Canon digital SLR cameras fail to adjust the effective sensor resolution when shooting at less
|
399
|
-
than full resolution, causing jhead to incorrectly miscalculate the sensor width and 35mm equivalent
|
400
|
-
focal length. The same can result from resizing photos with Photoshop, which will manipulate
|
401
|
-
parts of the exif header.
|
402
|
-
This is often reported as a bug in Jhead, but Jhead can't do much about incorrect data.
|
403
|
-
.PP
|
404
|
-
Send bug reports to mwandel at sentex dot net.
|
405
|
-
|
406
|
-
.SH COPYING PERMISSIONS
|
407
|
-
Jhead is 'public domain'. You may freely copy jhead, and reuse part or all of its code
|
408
|
-
in free or proprietary programs. I do however request that you do not post my e-mail
|
409
|
-
address in ways that spam robots can harvest it.
|