No issues found
1 /*
2 * Copyright (C) 2010, 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 <libtracker-common/tracker-file-utils.h>
23 #include <libtracker-extract/tracker-extract.h>
24
25 #define ICON_HEADER_SIZE_16 3
26 #define ICON_IMAGE_METADATA_SIZE_8 16
27
28 static gboolean
29 find_max_width_and_height (const gchar *uri,
30 guint *width,
31 guint *height)
32 {
33 GError *error = NULL;
34 GFile *file;
35 GFileInputStream *stream;
36 guint n_images;
37 guint i;
38 guint16 header [ICON_HEADER_SIZE_16];
39
40 *width = 0;
41 *height = 0;
42
43 file = g_file_new_for_uri (uri);
44 stream = g_file_read (file, NULL, &error);
45 if (error) {
46 g_message ("Could not read file '%s': %s",
47 uri,
48 error->message);
49 g_error_free (error);
50 g_object_unref (file);
51
52 return FALSE;
53 }
54
55 /* Header consists of:
56 * - 2bytes, reserved, must be 0
57 * - 2bytes, image type (1:icon, 2:cursor, other values invalid)
58 * - 2bytes, number of images in the file.
59 *
60 * Right now we just need the number of images in the file.
61 */
62 if (!g_input_stream_read_all (G_INPUT_STREAM (stream),
63 header,
64 ICON_HEADER_SIZE_16 * 2,
65 NULL,
66 NULL,
67 &error)) {
68 g_message ("Error reading icon header from stream: '%s'",
69 error->message);
70 g_error_free (error);
71 g_object_unref (stream);
72 g_object_unref (file);
73 return FALSE;
74 }
75
76 n_images = GUINT16_FROM_LE (header[2]);
77 g_debug ("Found '%u' images in the icon file...", n_images);
78
79 /* Loop images looking for the biggest one... */
80 for (i = 0; i < n_images; i++) {
81 guint8 image_metadata [ICON_IMAGE_METADATA_SIZE_8];
82
83 /* Image metadata chunk consists of:
84 * - 1 byte, width in pixels, 0 means 256
85 * - 1 byte, height in pixels, 0 means 256
86 * - Plus some other stuff we don't care about...
87 */
88 if (!g_input_stream_read_all (G_INPUT_STREAM (stream),
89 image_metadata,
90 ICON_IMAGE_METADATA_SIZE_8,
91 NULL,
92 NULL,
93 &error)) {
94 g_message ("Error reading icon image metadata '%u' from stream: '%s'",
95 i,
96 error->message);
97 g_error_free (error);
98 break;
99 }
100
101 g_debug (" Image '%u'; width:%u height:%u",
102 i,
103 image_metadata[0],
104 image_metadata[1]);
105
106 /* Width... */
107 if (image_metadata[0] == 0) {
108 *width = 256;
109 } else if (image_metadata[0] > *width) {
110 *width = image_metadata[0];
111 }
112
113 /* Height... */
114 if (image_metadata[1] == 0) {
115 *height = 256;
116 } else if (image_metadata[1] > *width) {
117 *height = image_metadata[0];
118 }
119 }
120
121 g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
122 g_object_unref (stream);
123 g_object_unref (file);
124 return TRUE;
125 }
126
127 G_MODULE_EXPORT gboolean
128 tracker_extract_get_metadata (TrackerExtractInfo *info)
129 {
130 TrackerSparqlBuilder *metadata;
131 guint max_width;
132 guint max_height;
133 GFile *file;
134 gchar *uri;
135
136 metadata = tracker_extract_info_get_metadata_builder (info);
137 file = tracker_extract_info_get_file (info);
138 uri = g_file_get_uri (file);
139
140 /* The Windows Icon file format may contain the same icon with different
141 * sizes inside, so there's no clear way of setting single width and
142 * height values. Thus, we set maximum sizes found. */
143 tracker_sparql_builder_predicate (metadata, "a");
144 tracker_sparql_builder_object (metadata, "nfo:Image");
145 tracker_sparql_builder_object (metadata, "nfo:Icon");
146
147 if (find_max_width_and_height (uri, &max_width, &max_height)) {
148 if (max_width > 0) {
149 tracker_sparql_builder_predicate (metadata, "nfo:width");
150 tracker_sparql_builder_object_int64 (metadata, (gint64) max_width);
151 }
152 if (max_height > 0) {
153 tracker_sparql_builder_predicate (metadata, "nfo:height");
154 tracker_sparql_builder_object_int64 (metadata, (gint64) max_height);
155 }
156 }
157
158 g_free (uri);
159
160 return TRUE;
161 }