Updated.
[platform/upstream/libexif.git] / libexif / exif-content.c
1 /* exif-content.c
2  *
3  * Copyright (C) 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 #include <config.h>
21 #include "exif-content.h"
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 //#define DEBUG
28
29 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
30
31 struct _ExifContentPrivate
32 {
33         unsigned int ref_count;
34 };
35
36 ExifContent *
37 exif_content_new (void)
38 {
39         ExifContent *content;
40
41         content = malloc (sizeof (ExifContent));
42         if (!content)
43                 return (NULL);
44         memset (content, 0, sizeof (ExifContent));
45         content->priv = malloc (sizeof (ExifContentPrivate));
46         if (!content->priv) {
47                 free (content);
48                 return (NULL);
49         }
50         memset (content->priv, 0, sizeof (ExifContentPrivate));
51         content->priv->ref_count = 1;
52
53         return (content);
54 }
55
56 void
57 exif_content_ref (ExifContent *content)
58 {
59         content->priv->ref_count++;
60 }
61
62 void
63 exif_content_unref (ExifContent *content)
64 {
65         content->priv->ref_count--;
66         if (!content->priv->ref_count)
67                 exif_content_free (content);
68 }
69
70 void
71 exif_content_free (ExifContent *content)
72 {
73         unsigned int i;
74
75         for (i = 0; i < content->count; i++)
76                 exif_entry_unref (content->entries[i]);
77         free (content->entries);
78         free (content->priv);
79         free (content);
80 }
81
82 void
83 exif_content_parse (ExifContent *content, const unsigned char *data,
84                     unsigned int size, unsigned int offset,
85                     ExifByteOrder order)
86 {
87         unsigned int i;
88         ExifShort n;
89         ExifEntry *entry;
90
91         if (!content)
92                 return;
93
94         content->order = order;
95
96         /* Read number of entries */
97         if (size < offset + 2)
98                 return;
99         n = exif_get_short (data + offset, order);
100 #ifdef DEBUG
101         printf ("Parsing directory with %i entries...\n", n);
102 #endif
103
104         for (i = 0; i < n; i++) {
105                 entry = exif_entry_new ();
106                 exif_content_add_entry (content, entry);
107                 exif_entry_parse (content->entries[i], data, size,
108                                   offset + 2 + 12 * i, order);
109                 exif_entry_unref (entry);
110         }
111 }
112
113 void
114 exif_content_dump (ExifContent *content, unsigned int indent)
115 {
116         char buf[1024];
117         unsigned int i;
118
119         for (i = 0; i < 2 * indent; i++)
120                 buf[i] = ' ';
121         buf[i] = '\0';
122
123         if (!content)
124                 return;
125
126         printf ("%sDumping exif content (%i entries)...\n", buf,
127                 content->count);
128         for (i = 0; i < content->count; i++)
129                 exif_entry_dump (content->entries[i], indent + 1);
130 }
131
132 void
133 exif_content_add_entry (ExifContent *content, ExifEntry *entry)
134 {
135         if (entry->parent)
136                 return;
137
138         entry->parent = content;
139         content->entries = realloc (content->entries,
140                                     sizeof (ExifEntry) * (content->count + 1));
141         content->entries[content->count] = entry;
142         exif_entry_ref (entry);
143         content->count++;
144 }
145
146 void
147 exif_content_remove_entry (ExifContent *content, ExifEntry *entry)
148 {
149         unsigned int i;
150
151         if (entry->parent != content)
152                 return;
153
154         for (i = 0; i < content->count; i++)
155                 if (content->entries[i] == entry)
156                         break;
157         if (i == content->count)
158                 return;
159
160         memmove (&content->entries[i], &content->entries[i + 1],
161                  sizeof (ExifEntry) * (content->count - i - 1));
162         content->count--;
163
164         entry->parent = NULL;
165         exif_entry_unref (entry);
166 }
167
168 ExifEntry *
169 exif_content_get_entry (ExifContent *content, ExifTag tag)
170 {
171         unsigned int i;
172
173         if (!content)
174                 return (NULL);
175
176         for (i = 0; i < content->count; i++)
177                 if (content->entries[i]->tag == tag)
178                         return (content->entries[i]);
179         return (NULL);
180 }