4 tags.c - functions for manipulating an images tags list
10 i_tags_destroy(&tags);
11 i_tags_addn(&tags, "name", code, idata);
12 i_tags_add(&tags, "name", code, data, data_size, idata);
13 if (i_tags_find(&tags, name, start, &entry)) { found }
14 if (i_tags_findn(&tags, code, start, &entry)) { found }
15 i_tags_delete(&tags, index);
16 count = i_tags_delbyname(tags, name);
17 count = i_tags_delbycode(tags, code);
21 Provides functions which give write access to the tags list of an image.
23 For read access directly access the fields (do not write any fields
26 A tag is represented by an i_img_tag structure:
34 char *name; // name of a given tag, might be NULL
35 int code; // number of a given tag, -1 if it has no meaning
36 char *data; // value of a given tag if it's not an int, may be NULL
37 int size; // size of the data
38 int idata; // value of a given tag if data is NULL
51 /* useful for debugging */
52 void i_tags_print(i_img_tags *tags);
55 =item i_tags_new(i_img_tags *tags)
57 Initialize a tags structure. Should not be used if the tags structure
58 has been previously used.
60 To destroy the contents use i_tags_destroy()
65 void i_tags_new(i_img_tags *tags) {
66 tags->count = tags->alloc = 0;
71 =item i_tags_addn(i_img_tags *tags, char *name, int code, int idata)
73 Adds a tag that has an integer value. A simple wrapper around i_tags_add().
75 Duplicate tags can be added.
77 Returns non-zero on success.
82 int i_tags_addn(i_img_tags *tags, char *name, int code, int idata) {
83 return i_tags_add(tags, name, code, NULL, 0, idata);
87 =item i_tags_add(i_img_tags *tags, char *name, int code, char *data, int size, i_tag_type type, int idata)
89 Adds a tag to the tags list.
91 Duplicate tags can be added.
93 Returns non-zero on success.
98 int i_tags_add(i_img_tags *tags, char *name, int code, char *data, int size,
100 i_img_tag work = {0};
101 if (tags->tags == NULL) {
103 tags->tags = mymalloc(sizeof(i_img_tag) * alloc);
108 else if (tags->count == tags->alloc) {
109 int newalloc = tags->alloc + 10;
110 void *newtags = myrealloc(tags->tags, sizeof(i_img_tag) * newalloc);
114 tags->tags = newtags;
115 tags->alloc = newalloc;
118 work.name = mymalloc(strlen(name)+1);
121 strcpy(work.name, name);
124 work.data = mymalloc(size+1);
126 if (work.name) myfree(work.name);
129 memcpy(work.data, data, size);
130 work.data[size] = '\0'; /* convenience */
135 tags->tags[tags->count++] = work;
140 void i_tags_destroy(i_img_tags *tags) {
143 for (i = 0; i < tags->count; ++i) {
144 if (tags->tags[i].name)
145 myfree(tags->tags[i].name);
146 if (tags->tags[i].data)
147 myfree(tags->tags[i].data);
153 int i_tags_find(i_img_tags *tags, char *name, int start, int *entry) {
155 while (start < tags->count) {
156 if (tags->tags[start].name && strcmp(name, tags->tags[start].name) == 0) {
166 int i_tags_findn(i_img_tags *tags, int code, int start, int *entry) {
168 while (start < tags->count) {
169 if (tags->tags[start].code == code) {
179 int i_tags_delete(i_img_tags *tags, int entry) {
180 if (tags->tags && entry >= 0 && entry < tags->count) {
181 i_img_tag old = tags->tags[entry];
182 memmove(tags->tags+entry, tags->tags+entry+1,
183 tags->count-entry-1);
194 int i_tags_delbyname(i_img_tags *tags, char *name) {
198 for (i = tags->count-1; i >= 0; --i) {
199 if (tags->tags[i].name && strcmp(name, tags->tags[i].name) == 0) {
201 i_tags_delete(tags, i);
208 int i_tags_delbycode(i_img_tags *tags, int code) {
212 for (i = tags->count-1; i >= 0; --i) {
213 if (tags->tags[i].code == code) {
215 i_tags_delete(tags, i);
222 int i_tags_get_float(i_img_tags *tags, char *name, int code, double *value) {
227 if (!i_tags_find(tags, name, 0, &index))
231 if (!i_tags_findn(tags, code, 0, &index))
234 entry = tags->tags+index;
236 *value = atof(entry->data);
238 *value = entry->idata;
243 int i_tags_set_float(i_img_tags *tags, char *name, int code, double value) {
246 sprintf(temp, "%.30g", value);
248 i_tags_delbyname(tags, name);
250 i_tags_delbycode(tags, code);
252 return i_tags_add(tags, name, code, temp, strlen(temp), 0);
255 int i_tags_get_int(i_img_tags *tags, char *name, int code, int *value) {
260 if (!i_tags_find(tags, name, 0, &index))
264 if (!i_tags_findn(tags, code, 0, &index))
267 entry = tags->tags+index;
269 *value = atoi(entry->data);
271 *value = entry->idata;
276 int i_tags_get_string(i_img_tags *tags, char *name, int code,
277 char *value, size_t value_size) {
282 if (!i_tags_find(tags, name, 0, &index))
286 if (!i_tags_findn(tags, code, 0, &index))
289 entry = tags->tags+index;
291 size_t cpsize = value_size < entry->size ? value_size : entry->size;
292 memcpy(value, entry->data, cpsize);
293 if (cpsize == value_size)
295 value[cpsize] = '\0';
298 sprintf(value, "%d", entry->data);
304 void i_tags_print(i_img_tags *tags) {
306 printf("Alloc %d\n", tags->alloc);
307 printf("Count %d\n", tags->count);
308 for (i = 0; i < tags->count; ++i) {
309 i_img_tag *tag = tags->tags + i;
310 printf("Tag %d\n", i);
312 printf(" Name : %s\n", tag->name);
313 printf(" Code : %d\n", tag->code);
316 printf(" Data : %d => '", tag->size);
317 for (pos = 0; pos < tag->size; ++pos) {
318 if (tag->data[pos] == '\\' || tag->data[pos] == '\'') {
320 putchar(tag->data[pos]);
322 else if (tag->data[pos] < ' ' || tag->data[pos] >= '\x7E')
323 printf("\\x%02X", tag->data[pos]);
325 putchar(tag->data[pos]);
328 printf(" Idata: %d\n", tag->idata);
338 Tony Cook <tony@develop-help.com>