No issues found
1 /*
2 * Copyright (C) 2011, Nokia <ivan.frade@nokia.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <setjmp.h>
25
26 #include <jpeglib.h>
27
28 #include <glib.h>
29 #include <gio/gio.h>
30 #include <libtracker-extract/tracker-iptc.h>
31
32 #define PS3_NAMESPACE "Photoshop 3.0\0"
33 #define PS3_NAMESPACE_LENGTH 14
34 #include <libiptcdata/iptc-jpeg.h>
35
36 struct tej_error_mgr {
37 struct jpeg_error_mgr jpeg;
38 jmp_buf setjmp_buffer;
39 };
40
41
42 static void
43 extract_jpeg_error_exit (j_common_ptr cinfo)
44 {
45 struct tej_error_mgr *h = (struct tej_error_mgr *) cinfo->err;
46 (*cinfo->err->output_message)(cinfo);
47 longjmp (h->setjmp_buffer, 1);
48 }
49
50 /*
51 * libiptcdata doesn't scan the file until find the IPTC blob.
52 * We need to find the blob ourselves. This code comes from tracker-extract-jpeg
53 */
54 static TrackerIptcData *
55 load_iptc_blob (const gchar *filename)
56 {
57 struct jpeg_decompress_struct cinfo;
58 struct tej_error_mgr tejerr;
59 struct jpeg_marker_struct *marker;
60 TrackerIptcData *id = NULL;
61 FILE *f;
62 gchar *uri;
63 GFile *file;
64
65 file = g_file_new_for_path (filename);
66 uri = g_file_get_uri (file);
67 g_object_unref (file);
68
69 f = fopen (filename, "r");
70
71 cinfo.err = jpeg_std_error (&tejerr.jpeg);
72 tejerr.jpeg.error_exit = extract_jpeg_error_exit;
73 if (setjmp (tejerr.setjmp_buffer)) {
74 fclose (f);
75 g_free (uri);
76 return NULL;
77 }
78
79 jpeg_create_decompress (&cinfo);
80
81 jpeg_save_markers (&cinfo, JPEG_COM, 0xFFFF);
82 jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xFFFF);
83 jpeg_save_markers (&cinfo, JPEG_APP0 + 13, 0xFFFF);
84
85 jpeg_stdio_src (&cinfo, f);
86
87 jpeg_read_header (&cinfo, TRUE);
88
89 marker = (struct jpeg_marker_struct *) &cinfo.marker_list;
90
91 while (marker) {
92 gchar *str;
93 gsize len;
94 gint offset;
95 guint sublen;
96
97 switch (marker->marker) {
98 case JPEG_COM:
99 break;
100
101 case JPEG_APP0 + 1:
102 break;
103
104 case JPEG_APP0 + 13:
105 str = (gchar*) marker->data;
106 len = marker->data_length;
107 if (len > 0 && strncmp (PS3_NAMESPACE, str, PS3_NAMESPACE_LENGTH) == 0) {
108 offset = iptc_jpeg_ps3_find_iptc ((guchar *)str, len, &sublen);
109 if (offset > 0 && sublen > 0) {
110 id = tracker_iptc_new ((const guchar *)str + offset, sublen, uri);
111 }
112 }
113 break;
114
115 default:
116 marker = marker->next;
117 continue;
118 }
119
120 marker = marker->next;
121 }
122
123 g_free (uri);
124 fclose (f);
125
126 return id;
127 }
128
129 static void
130 test_iptc_extraction (void)
131 {
132 TrackerIptcData *data;
133
134 data = load_iptc_blob (TOP_SRCDIR "/tests/libtracker-extract/iptc-img.jpg");
135 g_assert (data);
136
137 g_assert_cmpstr (data->keywords, ==, "Coverage, test");
138 g_assert (g_str_has_prefix (data->date_created, "2011-10-22"));
139 g_assert_cmpstr (data->byline, ==, "BylineValue");
140 g_assert_cmpstr (data->byline_title, ==, "BylineTitleValue");
141 g_assert_cmpstr (data->credit, ==, "CreditValue");
142 g_assert_cmpstr (data->copyright_notice, ==, "IptcToolAuthors");
143 g_assert_cmpstr (data->image_orientation, ==, "nfo:orientation-left");
144 g_assert_cmpstr (data->city, ==, "Helsinki");
145 g_assert_cmpstr (data->state, ==, "N/A");
146 g_assert_cmpstr (data->sublocation, ==, "Ruoholahti");
147 g_assert_cmpstr (data->country_name, ==, "Finland");
148 g_assert_cmpstr (data->contact, ==, "Dilbert");
149
150 tracker_iptc_free (data);
151 }
152
153 int
154 main (int argc, char **argv)
155 {
156 g_test_init (&argc, &argv, NULL);
157
158 g_test_add_func ("/libtracker-extract/iptc/extraction",
159 test_iptc_extraction);
160 return g_test_run ();
161 }