-
Notifications
You must be signed in to change notification settings - Fork 0
/
jhead.h
300 lines (255 loc) · 9.6 KB
/
jhead.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
//--------------------------------------------------------------------------
// Include file for jhead program.
//
// This include file only defines stuff that goes across modules.
// I like to keep the definitions for macros and structures as close to
// where they get used as possible, so include files only get stuff that
// gets used in more than one file.
//--------------------------------------------------------------------------
#define _CRT_SECURE_NO_DEPRECATE 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
#include <stdint.h>
//--------------------------------------------------------------------------
#ifdef _WIN32
#include <sys/utime.h>
#else
#include <utime.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#endif
typedef unsigned char uchar;
typedef unsigned long long ullong;
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define MAX_COMMENT_SIZE 2000
#define GPS_PROCESSING_METHOD_LEN 100
#ifdef _WIN32
#define PATH_MAX _MAX_PATH
#define SLASH '\\'
#else
#define SLASH '/'
#endif
//--------------------------------------------------------------------------
// This structure is used to store jpeg file sections in memory.
typedef struct {
uchar * Data;
int Type;
unsigned Offset;
unsigned Size;
}Section_t;
extern int ExifSectionIndex;
extern int DumpExifMap;
#define MAX_DATE_COPIES 10
// Buffer size must large enough to hold maximum location string
// containing six signed integers plus delimeters and terminator,
// i.e.: 11 * 6 + 3(‘/’) + 2(’,’) + 1(\0) = 72
#define MAX_BUF_SIZE 72
// Sub second tag string length (including null termination character), with
// nano-second precision. e.g. 0.123456789s is represented as a null terminated
// string "123456789". Although it can be any length, it is limited to 9 digits
// here as we limit the precision to nano-second.
#define SUB_SEC_SIZE 10
typedef struct {
uint32_t num;
uint32_t denom;
} rat_t;
//--------------------------------------------------------------------------
// This structure stores Exif header image elements in a simple manner
// Used to store camera data as extracted from the various ways that it can be
// stored in an exif header
typedef struct {
char FileName [PATH_MAX+1];
time_t FileDateTime;
unsigned FileSize;
char CameraMake [32];
char CameraModel [40];
char DateTime [20];
char DigitizedTime[20];
// Fractions of seconds for DateTime tag, with milisecond precision.
char SubSecTime[SUB_SEC_SIZE];
// Fractions of seconds for DateTimeOriginal tag, with milisecond precision.
char SubSecTimeOrig[SUB_SEC_SIZE];
// Fractions of seconds for DateTimeDigitized tag, with milisecond precision.
char SubSecTimeDig[SUB_SEC_SIZE];
int Height, Width;
int Orientation;
int IsColor;
int Process;
int FlashUsed;
rat_t FocalLength;
float ExposureTime;
float ApertureFNumber;
float Distance;
float CCDWidth;
float ExposureBias;
float DigitalZoomRatio;
int FocalLength35mmEquiv; // Exif 2.2 tag - usually not present.
int Whitebalance;
int MeteringMode;
int ExposureProgram;
int ExposureMode;
int ISOequivalent;
int LightSource;
int DistanceRange;
char Comments[MAX_COMMENT_SIZE];
int CommentWidchars; // If nonzer, widechar comment, indicates number of chars.
unsigned ThumbnailOffset; // Exif offset to thumbnail
unsigned ThumbnailSize; // Size of thumbnail.
unsigned LargestExifOffset; // Last exif data referenced (to check if thumbnail is at end)
char ThumbnailAtEnd; // Exif header ends with the thumbnail
// (we can only modify the thumbnail if its at the end)
int ThumbnailSizeOffset;
int DateTimeOffsets[MAX_DATE_COPIES];
int numDateTimeTags;
int GpsInfoPresent;
char GpsLat[31];
char GpsLatRaw[MAX_BUF_SIZE];
char GpsLatRef[2];
char GpsLong[31];
char GpsLongRaw[MAX_BUF_SIZE];
char GpsLongRef[2];
char GpsAlt[20];
rat_t GpsAltRaw;
char GpsAltRef;
// gps-datestamp is 11 bytes ascii in EXIF 2.2
char GpsDateStamp[11];
char GpsTimeStamp[11];
char GpsProcessingMethod[GPS_PROCESSING_METHOD_LEN + 1];
}ImageInfo_t;
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
// jpgfile.c functions
typedef enum {
READ_METADATA = 1,
READ_IMAGE = 2,
READ_ALL = 3
}ReadMode_t;
typedef struct {
unsigned short Tag; // tag value, i.e. TAG_MODEL
int Format; // format of data
char* Value; // value of data in string format
int DataLength; // length of string when format says Value is a string
int GpsTag; // bool - the tag is related to GPS info
} ExifElement_t;
typedef struct {
unsigned short Tag;
char * Desc;
int Format;
int DataLength; // Number of elements in Format. -1 means any length.
} TagTable_t;
// prototypes for jhead.c functions
void ErrFatal(char * msg);
void ErrNonfatal(char * msg, int a1, int a2);
void FileTimeAsString(char * TimeStr);
// Prototypes for exif.c functions.
int Exif2tm(struct tm * timeptr, char * ExifTime);
void process_EXIF (unsigned char * CharBuf, unsigned int length);
int RemoveThumbnail(unsigned char * ExifSection);
void ShowImageInfo(int ShowFileInfo);
void ShowConciseImageInfo(void);
const char * ClearOrientation(void);
void PrintFormatNumber(void * ValuePtr, int Format, int ByteCount);
double ConvertAnyFormat(void * ValuePtr, int Format);
int Get16u(void * Short);
unsigned Get32u(void * Long);
int Get32s(void * Long);
void Put32u(void * Value, unsigned PutValue);
void create_EXIF(ExifElement_t* elements, int exifTagCount, int gpsTagCount, int hasDateTimeTag);
int TagNameToValue(const char* tagName);
int IsDateTimeTag(unsigned short tag);
//--------------------------------------------------------------------------
// Exif format descriptor stuff
extern const int BytesPerFormat[];
#define NUM_FORMATS 12
#define FMT_BYTE 1
#define FMT_STRING 2
#define FMT_USHORT 3
#define FMT_ULONG 4
#define FMT_URATIONAL 5
#define FMT_SBYTE 6
#define FMT_UNDEFINED 7
#define FMT_SSHORT 8
#define FMT_SLONG 9
#define FMT_SRATIONAL 10
#define FMT_SINGLE 11
#define FMT_DOUBLE 12
// makernote.c prototypes
extern void ProcessMakerNote(unsigned char * DirStart, int ByteCount,
unsigned char * OffsetBase, unsigned ExifLength);
// gpsinfo.c prototypes
void ProcessGpsInfo(unsigned char * ValuePtr, int ByteCount,
unsigned char * OffsetBase, unsigned ExifLength);
int IsGpsTag(const char* tag);
int GpsTagToFormatType(unsigned short tag);
int GpsTagNameToValue(const char* tagName);
TagTable_t* GpsTagToTagTableEntry(unsigned short tag);
static const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
// iptc.c prototpyes
void show_IPTC (unsigned char * CharBuf, unsigned int length);
void ShowXmp(Section_t XmpSection);
// Prototypes for myglob.c module
#ifdef _WIN32
void MyGlob(const char * Pattern , void (*FileFuncParm)(const char * FileName));
void SlashToNative(char * Path);
#endif
// Prototypes for paths.c module
int EnsurePathExists(const char * FileName);
void CatPath(char * BasePath, const char * FilePath);
// Prototypes from jpgfile.c
int ReadJpegSections (FILE * infile, ReadMode_t ReadMode);
void DiscardData(void);
void DiscardAllButExif(void);
int ReadJpegFile(const char * FileName, ReadMode_t ReadMode);
int ReplaceThumbnail(const char * ThumbFileName);
int ReplaceThumbnailFromBuffer(const char* Thumb, int ThumbLen);
int SaveThumbnail(char * ThumbFileName);
int RemoveSectionType(int SectionType);
int RemoveUnknownSections(void);
int WriteJpegFile(const char * FileName);
Section_t * FindSection(int SectionType);
Section_t * CreateSection(int SectionType, unsigned char * Data, int size);
void ResetJpgfile(void);
int ReadJpegSectionsFromBuffer (unsigned char* buffer, unsigned int buffer_size, ReadMode_t ReadMode);
int WriteJpegToBuffer(unsigned char* buffer, unsigned int buffer_size);
// Variables from jhead.c used by exif.c
extern ImageInfo_t ImageInfo;
extern int ShowTags;
extern char* formatStr(int format);
//--------------------------------------------------------------------------
// JPEG markers consist of one or more 0xFF bytes, followed by a marker
// code byte (which is not an FF). Here are the marker codes of interest
// in this program. (See jdmarker.c for a more complete list.)
//--------------------------------------------------------------------------
#define M_SOF0 0xC0 // Start Of Frame N
#define M_SOF1 0xC1 // N indicates which compression process
#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use
#define M_SOF3 0xC3
#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers
#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 // Start Of Image (beginning of datastream)
#define M_EOI 0xD9 // End Of Image (end of datastream)
#define M_SOS 0xDA // Start Of Scan (begins compressed data)
#define M_JFIF 0xE0 // Jfif marker
#define M_EXIF 0xE1 // Exif marker. Also used for XMP data!
#define M_XMP 0x10E1 // Not a real tag (same value in file as Exif!)
#define M_COM 0xFE // COMment
#define M_DQT 0xDB
#define M_DHT 0xC4
#define M_DRI 0xDD
#define M_IPTC 0xED // IPTC marker