comment unused constant
[platform/upstream/libexif.git] / libexif / exif-content.c
1 /* exif-content.c
2  *
3  * Copyright © 2001 Lutz Müller <lutz@users.sourceforge.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22
23 #include <libexif/exif-content.h>
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 /* unused constant
30  * static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
31  */
32
33 struct _ExifContentPrivate
34 {
35         unsigned int ref_count;
36
37         ExifMem *mem;
38         ExifLog *log;
39 };
40
41 ExifContent *
42 exif_content_new (void)
43 {
44         ExifMem *mem = exif_mem_new_default ();
45         ExifContent *content = exif_content_new_mem (mem);
46
47         exif_mem_unref (mem);
48
49         return content;
50 }
51
52 ExifContent *
53 exif_content_new_mem (ExifMem *mem)
54 {
55         ExifContent *content;
56
57         if (!mem) return NULL;
58
59         content = exif_mem_alloc (mem, (ExifLong) sizeof (ExifContent));
60         if (!content)
61                 return NULL;
62         content->priv = exif_mem_alloc (mem,
63                                 (ExifLong) sizeof (ExifContentPrivate));
64         if (!content->priv) {
65                 exif_mem_free (mem, content);
66                 return NULL;
67         }
68
69         content->priv->ref_count = 1;
70
71         content->priv->mem = mem;
72         exif_mem_ref (mem);
73
74         return content;
75 }
76
77 void
78 exif_content_ref (ExifContent *content)
79 {
80         content->priv->ref_count++;
81 }
82
83 void
84 exif_content_unref (ExifContent *content)
85 {
86         content->priv->ref_count--;
87         if (!content->priv->ref_count)
88                 exif_content_free (content);
89 }
90
91 void
92 exif_content_free (ExifContent *content)
93 {
94         ExifMem *mem = (content && content->priv) ? content->priv->mem : NULL;
95         unsigned int i;
96
97         if (!content) return;
98
99         for (i = 0; i < content->count; i++)
100                 exif_entry_unref (content->entries[i]);
101         exif_mem_free (mem, content->entries);
102
103         if (content->priv) {
104                 exif_log_unref (content->priv->log);
105         }
106
107         exif_mem_free (mem, content->priv);
108         exif_mem_free (mem, content);
109         exif_mem_unref (mem);
110 }
111
112 void
113 exif_content_dump (ExifContent *content, unsigned int indent)
114 {
115         char buf[1024];
116         unsigned int i;
117
118         for (i = 0; i < 2 * indent; i++)
119                 buf[i] = ' ';
120         buf[i] = '\0';
121
122         if (!content)
123                 return;
124
125         printf ("%sDumping exif content (%i entries)...\n", buf,
126                 content->count);
127         for (i = 0; i < content->count; i++)
128                 exif_entry_dump (content->entries[i], indent + 1);
129 }
130
131 void
132 exif_content_add_entry (ExifContent *c, ExifEntry *entry)
133 {
134         if (!c || !c->priv || !entry || entry->parent) return;
135
136         /* One tag can only be added once to an IFD. */
137         if (exif_content_get_entry (c, entry->tag)) {
138                 exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "ExifContent",
139                         "An attempt has been made to add "
140                         "the tag '%s' twice to an IFD. This is against "
141                         "specification.", exif_tag_get_name (entry->tag));
142                 return;
143         }
144
145         entry->parent = c;
146         c->entries = exif_mem_realloc (c->priv->mem,
147                 c->entries, sizeof (ExifEntry) * (c->count + 1));
148         if (!c->entries) return;
149         c->entries[c->count] = entry;
150         exif_entry_ref (entry);
151         c->count++;
152 }
153
154 void
155 exif_content_remove_entry (ExifContent *c, ExifEntry *e)
156 {
157         unsigned int i;
158
159         if (!c || !c->priv || !e || (e->parent != c)) return;
160
161         /* Search the entry */
162         for (i = 0; i < c->count; i++) if (c->entries[i] == e) break;
163         if (i == c->count) return;
164
165         /* Remove the entry */
166         memmove (&c->entries[i], &c->entries[i + 1],
167                  sizeof (ExifEntry) * (c->count - i - 1));
168         c->count--;
169         e->parent = NULL;
170         exif_entry_unref (e);
171         c->entries = exif_mem_realloc (c->priv->mem, c->entries,
172                                         sizeof(ExifEntry) * c->count);
173 }
174
175 ExifEntry *
176 exif_content_get_entry (ExifContent *content, ExifTag tag)
177 {
178         unsigned int i;
179
180         if (!content)
181                 return (NULL);
182
183         for (i = 0; i < content->count; i++)
184                 if (content->entries[i]->tag == tag)
185                         return (content->entries[i]);
186         return (NULL);
187 }
188
189 void
190 exif_content_foreach_entry (ExifContent *content,
191                             ExifContentForeachEntryFunc func, void *data)
192 {
193         unsigned int i;
194
195         if (!content || !func)
196                 return;
197
198         for (i = 0; i < content->count; i++)
199                 func (content->entries[i], data);
200 }
201
202 void
203 exif_content_log (ExifContent *content, ExifLog *log)
204 {
205         if (!content || !content->priv || !log || content->priv->log == log)
206                 return;
207
208         if (content->priv->log) exif_log_unref (content->priv->log);
209         content->priv->log = log;
210         exif_log_ref (log);
211 }