EXIF library (libexif) Internals 0.6.26
test-value.c
Go to the documentation of this file.
1/* test-value.c
2 *
3 * Creates all the types of tags supported in exif_entry_initialize() and
4 * ensures that exif_entry_get_value() properly truncates the output of each
5 * one according to the buffer size available.
6 *
7 * Copyright 2002 Lutz Mueller <lutz@users.sourceforge.net>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA.
23 *
24 * SPDX-License-Identifier: LGPL-2.0-or-later
25 */
26
27#include <libexif/exif-utils.h>
28#include <libexif/exif-data.h>
29
30#include <assert.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35/*
36 * List of tags to test, one per default initialized type.
37 * There should be one for every block in exif_entry_initialize() and
38 * exif_entry_get_value().
39 */
40static const ExifTag trunc_test_tags[] = {
60};
61
62/*
63 * These tags produce different outputs depending on the amount of buffer space
64 * available.
65 */
66static const ExifTag nonuniform_test_tags[] = {
70};
71
72/*
73 * These tags need a nonzero rational number to be interesting.
74 * They must have space for a rational or srational created automatically by
75 * exif_entry_initialize().
76 */
77static const ExifTag rational_test_tags[] = {
87};
88
89/*
90 * Verify that the entry is properly truncated to the buffer length within
91 * exif_entry_get_value(). If uniform is zero, then only check that the
92 * resulting string fits within the buffer and don't check its content.
93 */
94static void check_entry_trunc(ExifEntry *e, int uniform)
95{
96 unsigned int i;
97 char v[1024], full[1024]; /* Large enough to never truncate output */
98
99 printf ("Tag 0x%x\n", (int) e->tag);
100
101 /* Get the full, untruncated string to use as the expected value */
102 exif_entry_get_value (e, full, sizeof(full));
103 printf ("Full: '%s'\n", full);
104
105 for (i = strlen(full); i > 0; i--) {
106 /* Make sure the buffer isn't NUL-terminated to begin with */
107 memset(v, '*', sizeof(v));
108 exif_entry_get_value (e, v, i);
109 /* Truncate the full string by one on each iteration */
110 full[i-1] = '\0';
111 if ((strlen(v) >= i) || (uniform && strcmp(full, v))) {
112 printf("Bad truncation!\n");
113 printf("Length %2i: '%s'\n", i, v);
114 exit(1);
115 }
116 }
117}
118
119int
120main (void)
121{
122 ExifData *data;
123 ExifEntry *e;
124 ExifMem *mem;
125 unsigned i;
126 static const ExifSRational r = {1., 20.}; /* a nonzero number */
127 static const char user_comment[] = "ASCII\0\0\0A Long User Comment";
128 static const char xp_comment[] = "U\0C\0S\0-\0002\0 \0C\0o\0m\0m\0e\0n\0t\0";
129 static const char interop[] = "R98";
130 static const char subsec[] = "130 ";
131 static const ExifRational gpsh = {12., 1.};
132 static const ExifRational gpsm = {34., 1.};
133 static const ExifRational gpss = {56780., 1000.};
134
135 data = exif_data_new ();
136 if (!data) {
137 fprintf (stderr, "Error running exif_data_new()\n");
138 exit(13);
139 }
140
141 /* Full initialization/truncation tests */
142 for (i=0; i < sizeof(trunc_test_tags)/sizeof(trunc_test_tags[0]); ++i) {
143 e = exif_entry_new ();
144 if (!e) {
145 fprintf (stderr, "Error running exif_entry_new()\n");
146 exit(13);
147 }
150 check_entry_trunc(e, 1);
153 }
154
155 /* Nonuniform initialization/truncation tests */
156 for (i=0; i < sizeof(nonuniform_test_tags)/sizeof(nonuniform_test_tags[0]);
157 ++i) {
158 e = exif_entry_new ();
159 if (!e) {
160 fprintf (stderr, "Error running exif_entry_new()\n");
161 exit(13);
162 }
165 check_entry_trunc(e, 0);
168 }
169
170 /* Rational number initialization/truncation tests */
171 for (i=0; i < sizeof(rational_test_tags)/sizeof(rational_test_tags[0]);
172 ++i) {
173 e = exif_entry_new ();
174 if (!e) {
175 fprintf (stderr, "Error running exif_entry_new()\n");
176 exit(13);
177 }
181 /* In case this tag needs an unsigned rational instead,
182 * fix the type automatically */
183 exif_entry_fix (e);
184 check_entry_trunc(e, 1);
187 }
188
189 /* Create a memory allocator to manage the remaining ExifEntry structs */
190 mem = exif_mem_new_default();
191 if (!mem) {
192 fprintf (stderr, "Out of memory\n");
193 exit(13);
194 }
195
196 /* EXIF_TAG_SUB_SEC_TIME initialization/truncation tests */
197 e = exif_entry_new_mem (mem);
198 if (!e) {
199 fprintf (stderr, "Out of memory\n");
200 exit(13);
201 }
204 e->size = sizeof(subsec); /* include NUL */
205 e->components = e->size;
206 /* Allocate memory to use for holding the tag data */
207 e->data = exif_mem_alloc(mem, e->size);
208 if (!e->data) {
209 fprintf (stderr, "Out of memory\n");
210 exit(13);
211 }
212 memcpy(e->data, subsec, e->size);
213 check_entry_trunc(e, 1);
216
217 /* EXIF_TAG_USER_COMMENT initialization/truncation tests */
218 e = exif_entry_new_mem (mem);
219 if (!e) {
220 fprintf (stderr, "Out of memory\n");
221 exit(13);
222 }
225 e->size = sizeof(user_comment) - 1;
226 e->components = e->size;
227 /* Allocate memory to use for holding the tag data */
228 e->data = exif_mem_alloc(mem, e->size);
229 if (!e->data) {
230 fprintf (stderr, "Out of memory\n");
231 exit(13);
232 }
233 memcpy(e->data, user_comment, e->size);
234 check_entry_trunc(e, 1);
237
238 /* EXIF_TAG_XP_COMMENT truncation tests */
239 e = exif_entry_new_mem (mem);
240 if (!e) {
241 fprintf (stderr, "Out of memory\n");
242 exit(13);
243 }
247 e->size = sizeof(xp_comment) - 1;
248 e->components = e->size;
249 /* Allocate memory to use for holding the tag data */
250 e->data = exif_mem_alloc(mem, e->size);
251 if (!e->data) {
252 fprintf (stderr, "Out of memory\n");
253 exit(13);
254 }
255 memcpy(e->data, xp_comment, e->size);
256 check_entry_trunc(e, 1);
259
260 /* EXIF_TAG_INTEROPERABILITY_VERSION truncation tests */
261 e = exif_entry_new_mem (mem);
262 if (!e) {
263 fprintf (stderr, "Out of memory\n");
264 exit(13);
265 }
268 e->format = EXIF_FORMAT_UNDEFINED; /* The spec says ASCII, but libexif
269 allows UNDEFINED */
270 e->size = sizeof(interop); /* include NUL */
271 e->components = e->size;
272 /* Allocate memory to use for holding the tag data */
273 e->data = exif_mem_alloc(mem, e->size);
274 if (!e->data) {
275 fprintf (stderr, "Out of memory\n");
276 exit(13);
277 }
278 memcpy(e->data, interop, e->size);
279 check_entry_trunc(e, 1);
282
283 /* EXIF_TAG_GPS_VERSION_ID truncation tests */
284 e = exif_entry_new_mem (mem);
285 if (!e) {
286 fprintf (stderr, "Out of memory\n");
287 exit(13);
288 }
291 assert(e->format == EXIF_FORMAT_BYTE);
292 assert(e->size == 4);
293 assert(e->components == e->size);
294 e->data[0] = 2;
295 e->data[1] = 2;
296 e->data[2] = 0;
297 e->data[3] = 0;
298 check_entry_trunc(e, 1);
301
302 /* EXIF_TAG_GPS_ALTITUDE_REF truncation tests */
303 e = exif_entry_new_mem (mem);
304 if (!e) {
305 fprintf (stderr, "Out of memory\n");
306 exit(13);
307 }
310 assert(e->format == EXIF_FORMAT_BYTE);
311 assert(e->size == 1);
312 assert(e->components == e->size);
313 e->data[0] = 1;
314 check_entry_trunc(e, 1);
317
318 /* EXIF_TAG_GPS_TIME_STAMP truncation tests */
319 e = exif_entry_new_mem (mem);
320 if (!e) {
321 fprintf (stderr, "Out of memory\n");
322 exit(13);
323 }
326 assert(e->format == EXIF_FORMAT_RATIONAL);
327 assert(e->components == 3);
332 check_entry_trunc(e, 1);
335
336 /* EXIF_TAG_SUBJECT_AREA truncation tests */
337 e = exif_entry_new_mem (mem);
338 if (!e) {
339 fprintf (stderr, "Out of memory\n");
340 exit(13);
341 }
345 /* This tag is interpreted differently depending on # components */
346 /* Rectangle */
347 e->components = 4;
349 /* Allocate memory to use for holding the tag data */
350 e->data = exif_mem_alloc(mem, e->size);
351 if (!e->data) {
352 fprintf (stderr, "Out of memory\n");
353 exit(13);
354 }
359 check_entry_trunc(e, 1);
360 /* Circle */
361 e->components = 3;
363 check_entry_trunc(e, 1);
364 /* Centre */
365 e->components = 2;
367 check_entry_trunc(e, 1);
368 /* Invalid */
369 e->components = 1;
371 check_entry_trunc(e, 1);
374
375 exif_mem_unref(mem);
376 exif_data_unref (data);
377
378 return 0;
379}
void exif_content_remove_entry(ExifContent *c, ExifEntry *e)
Remove an EXIF tag from an IFD.
void exif_content_add_entry(ExifContent *c, ExifEntry *entry)
Add an EXIF tag to an IFD.
void exif_data_unref(ExifData *data)
Definition exif-data.c:1110
ExifByteOrder exif_data_get_byte_order(ExifData *data)
Return the byte order in use by this EXIF structure.
Definition exif-data.c:1185
ExifData * exif_data_new(void)
Allocate a new ExifData.
Definition exif-data.c:98
Defines the ExifData type and the associated functions.
ExifEntry * exif_entry_new_mem(ExifMem *mem)
Reserve memory for and initialize new ExifEntry using the specified memory allocator.
Definition exif-entry.c:124
const char * exif_entry_get_value(ExifEntry *e, char *val, unsigned int maxlen)
Return a localized textual representation of the value of the EXIF entry.
Definition exif-entry.c:854
ExifEntry * exif_entry_new(void)
Reserve memory for and initialize a new ExifEntry.
Definition exif-entry.c:113
void exif_entry_unref(ExifEntry *e)
Decrease reference counter for ExifEntry.
Definition exif-entry.c:149
void exif_entry_fix(ExifEntry *e)
Fix the type or format of the given EXIF entry to bring it into spec.
Definition exif-entry.c:207
void exif_entry_initialize(ExifEntry *e, ExifTag tag)
Initialize an empty ExifEntry with default data in the correct format for the given tag.
unsigned char exif_format_get_size(ExifFormat format)
Return the raw size of the given EXIF data type.
Definition exif-format.c:68
@ EXIF_FORMAT_RATIONAL
Definition exif-format.h:39
@ EXIF_FORMAT_UNDEFINED
Definition exif-format.h:41
@ EXIF_FORMAT_SHORT
Definition exif-format.h:37
@ EXIF_FORMAT_BYTE
Definition exif-format.h:35
@ EXIF_IFD_GPS
Definition exif-ifd.h:35
@ EXIF_IFD_INTEROPERABILITY
Definition exif-ifd.h:36
@ EXIF_IFD_0
Definition exif-ifd.h:32
void exif_mem_unref(ExifMem *mem)
Unrefcount an ExifMem.
Definition exif-mem.c:83
void * exif_mem_alloc(ExifMem *mem, ExifLong ds)
Definition exif-mem.c:101
ExifMem * exif_mem_new_default(void)
Create a new ExifMem with default values for your convenience.
Definition exif-mem.c:117
ExifTag
EXIF tags.
Definition exif-tag.h:36
@ EXIF_TAG_FNUMBER
Definition exif-tag.h:84
@ EXIF_TAG_COLOR_SPACE
Definition exif-tag.h:132
@ EXIF_TAG_SUBJECT_LOCATION
Definition exif-tag.h:142
@ EXIF_TAG_SUB_SEC_TIME
Definition exif-tag.h:123
@ EXIF_TAG_ORIENTATION
Definition exif-tag.h:51
@ EXIF_TAG_INTEROPERABILITY_VERSION
Definition exif-tag.h:38
@ EXIF_TAG_EXIF_VERSION
Definition exif-tag.h:101
@ EXIF_TAG_EXPOSURE_TIME
Definition exif-tag.h:83
@ EXIF_TAG_DATE_TIME
Definition exif-tag.h:61
@ EXIF_TAG_MAX_APERTURE_VALUE
Definition exif-tag.h:113
@ EXIF_TAG_PLANAR_CONFIGURATION
Definition exif-tag.h:57
@ EXIF_TAG_RESOLUTION_UNIT
Definition exif-tag.h:58
@ EXIF_TAG_BITS_PER_SAMPLE
Definition exif-tag.h:42
@ EXIF_TAG_SUBJECT_DISTANCE
Definition exif-tag.h:114
@ EXIF_TAG_IMAGE_WIDTH
Definition exif-tag.h:40
@ EXIF_TAG_USER_COMMENT
Definition exif-tag.h:122
@ EXIF_TAG_APERTURE_VALUE
Definition exif-tag.h:110
@ EXIF_TAG_IMAGE_DESCRIPTION
Definition exif-tag.h:47
@ EXIF_TAG_FLASH_PIX_VERSION
Definition exif-tag.h:131
@ EXIF_TAG_FILE_SOURCE
Definition exif-tag.h:145
@ EXIF_TAG_SCENE_TYPE
Definition exif-tag.h:146
@ EXIF_TAG_COPYRIGHT
Definition exif-tag.h:82
@ EXIF_TAG_COMPONENTS_CONFIGURATION
Definition exif-tag.h:107
@ EXIF_TAG_SHUTTER_SPEED_VALUE
Definition exif-tag.h:109
@ EXIF_TAG_PIXEL_X_DIMENSION
Definition exif-tag.h:133
@ EXIF_TAG_YCBCR_SUB_SAMPLING
Definition exif-tag.h:71
@ EXIF_TAG_SAMPLES_PER_PIXEL
Definition exif-tag.h:52
@ EXIF_TAG_EXPOSURE_BIAS_VALUE
Definition exif-tag.h:112
@ EXIF_TAG_REFERENCE_BLACK_WHITE
Definition exif-tag.h:73
@ EXIF_TAG_FOCAL_LENGTH
Definition exif-tag.h:118
@ EXIF_TAG_BRIGHTNESS_VALUE
Definition exif-tag.h:111
@ EXIF_TAG_SUBJECT_AREA
Definition exif-tag.h:119
@ EXIF_TAG_X_RESOLUTION
Definition exif-tag.h:55
@ EXIF_TAG_WHITE_POINT
Definition exif-tag.h:63
@ EXIF_TAG_XP_COMMENT
Definition exif-tag.h:127
@ EXIF_TAG_METERING_MODE
Definition exif-tag.h:115
#define EXIF_TAG_GPS_TIME_STAMP
Definition exif-tag.h:183
#define EXIF_TAG_GPS_VERSION_ID
Definition exif-tag.h:176
#define EXIF_TAG_GPS_ALTITUDE_REF
Definition exif-tag.h:181
void exif_set_rational(unsigned char *buf, ExifByteOrder order, ExifRational value)
Store an ExifRational value into memory in EXIF format.
Definition exif-utils.c:201
void exif_set_srational(unsigned char *buf, ExifByteOrder order, ExifSRational value)
Store an ExifSRational value into memory in EXIF format.
Definition exif-utils.c:210
void exif_set_short(unsigned char *b, ExifByteOrder order, ExifShort value)
Store an ExifShort value into memory in EXIF format.
Definition exif-utils.c:126
EXIF data manipulation functions and types.
EXIF Unsigned Rational data type.
Definition exif-utils.h:62
EXIF Signed Rational data type.
Definition exif-utils.h:67
Represents the entire EXIF data found in an image.
Definition exif-data.h:48
ExifContent * ifd[EXIF_IFD_COUNT]
Data for each IFD.
Definition exif-data.h:50
Data found in one EXIF tag.
Definition exif-entry.h:45
unsigned long components
Number of elements in the array, if this is an array entry.
Definition exif-entry.h:54
ExifFormat format
Type of data in this entry.
Definition exif-entry.h:50
unsigned char * data
Pointer to the raw EXIF data for this entry.
Definition exif-entry.h:59
ExifTag tag
EXIF tag for this entry.
Definition exif-entry.h:47
unsigned int size
Number of bytes in the buffer at data.
Definition exif-entry.h:63
static const ExifTag rational_test_tags[]
Definition test-value.c:77
static void check_entry_trunc(ExifEntry *e, int uniform)
Definition test-value.c:94
static const ExifTag nonuniform_test_tags[]
Definition test-value.c:66
int main(void)
Definition test-value.c:120
static const ExifTag trunc_test_tags[]
Definition test-value.c:40

libexif Generated by doxygen