2
* * Copyright (C) 2006-2011 Anders Brander <anders@brander.dk>,
3
* * Anders Kvist <akv@lnxbx.dk> and Klaus Post <klauspost@gmail.com>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
#include <rawstudio.h>
21
#include "rs-tiff-ifd.h"
23
G_DEFINE_TYPE (RSTiffIfd, rs_tiff_ifd, G_TYPE_OBJECT)
25
static void read_entries(RSTiffIfd *ifd);
35
rs_tiff_ifd_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
37
RSTiffIfd *ifd = RS_TIFF_IFD(object);
42
g_value_set_uint(value, ifd->next_ifd);
45
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
50
rs_tiff_ifd_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
52
RSTiffIfd *ifd = RS_TIFF_IFD(object);
57
ifd->tiff = g_object_ref(g_value_get_object(value));
58
if (ifd->tiff && ifd->offset)
59
RS_TIFF_IFD_GET_CLASS(ifd)->read(ifd);
62
ifd->offset = g_value_get_uint(value);
63
if (ifd->tiff && ifd->offset)
64
RS_TIFF_IFD_GET_CLASS(ifd)->read(ifd);
67
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
72
rs_tiff_ifd_dispose(GObject *object)
74
RSTiffIfd *ifd = RS_TIFF_IFD(object);
76
if (!ifd->dispose_has_run)
78
ifd->dispose_has_run = TRUE;
79
g_object_unref(ifd->tiff);
80
g_list_foreach(ifd->entries, (GFunc)g_object_unref, NULL);
81
g_list_free(ifd->entries);
84
G_OBJECT_CLASS(rs_tiff_ifd_parent_class)->dispose (object);
88
rs_tiff_ifd_finalize(GObject *object)
90
G_OBJECT_CLASS(rs_tiff_ifd_parent_class)->finalize (object);
94
rs_tiff_ifd_class_init(RSTiffIfdClass *klass)
96
GObjectClass *object_class = G_OBJECT_CLASS(klass);
98
object_class->get_property = rs_tiff_ifd_get_property;
99
object_class->set_property = rs_tiff_ifd_set_property;
100
object_class->dispose = rs_tiff_ifd_dispose;
101
object_class->finalize = rs_tiff_ifd_finalize;
103
g_object_class_install_property(object_class,
104
PROP_TIFF, g_param_spec_object(
105
"tiff", "tiff", "The RSTiff associated with the RSTiffIfd",
106
RS_TYPE_TIFF, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
108
g_object_class_install_property(object_class,
109
PROP_OFFSET, g_param_spec_uint(
110
"offset", "offset", "IFD offset",
111
0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
113
g_object_class_install_property(object_class,
114
PROP_NEXT_IFD, g_param_spec_uint(
115
"next-ifd", "next-ifd", "Offset for next ifd",
116
0, G_MAXUINT, 0, G_PARAM_READABLE));
118
klass->read = read_entries;
122
rs_tiff_ifd_init(RSTiffIfd *self)
127
rs_tiff_ifd_new(RSTiff *tiff, guint offset)
129
g_assert(RS_IS_TIFF(tiff));
131
return g_object_new(RS_TYPE_TIFF_IFD, "tiff", tiff, "offset", offset, NULL);
135
rs_tiff_ifd_get_next(RSTiffIfd *ifd)
137
g_assert(RS_IS_TIFF_IFD(ifd));
139
return ifd->next_ifd;
143
read_entries(RSTiffIfd *ifd)
147
ifd->num_entries = rs_tiff_get_ushort(ifd->tiff, ifd->offset);
148
ifd->next_ifd = rs_tiff_get_uint(ifd->tiff, ifd->offset + 2 + ifd->num_entries*12);
150
if (ifd->next_ifd == ifd->offset)
152
else if (ifd->next_ifd > (ifd->tiff->map_length-12))
155
/* Read all entries */
156
for(i=0;i<ifd->num_entries;i++)
157
ifd->entries = g_list_append(ifd->entries, rs_tiff_ifd_entry_new(ifd->tiff, ifd->offset + 2 + i * 12));
161
_tag_search(RSTiffIfdEntry *entry, gushort tag)
163
return entry->tag - tag;
167
rs_tiff_ifd_get_entry_by_tag(RSTiffIfd *ifd, gushort tag)
169
g_assert(RS_IS_TIFF_IFD(ifd));
171
RSTiffIfdEntry *ret = NULL;
173
found = g_list_find_custom(ifd->entries, GUINT_TO_POINTER((guint) tag), (GCompareFunc) _tag_search);
176
ret = g_object_ref(found->data);