tracker-0.16.2/src/tracker-extract/tracker-extract-jpeg.c

Location Tool Test ID Function Issue
tracker-extract-jpeg.c:253:5 gcc pointer-sign tracker_extract_get_metadata pointer targets in passing argument 1 of 'iptc_jpeg_ps3_find_iptc' differ in signedness
  1 /*
  2  * Copyright (C) 2006, Jamie McCracken <jamiemcc@gnome.org>
  3  * Copyright (C) 2008, Nokia <ivan.frade@nokia.com>
  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.1 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., 51 Franklin Street, Fifth Floor,
 18  * Boston, MA  02110-1301, USA.
 19  */
 20 
 21 #include "config.h"
 22 
 23 #include <stdio.h>
 24 #include <setjmp.h>
 25 
 26 #ifndef _GNU_SOURCE
 27 #define _GNU_SOURCE /* strcasestr() */
 28 #endif
 29 
 30 #include <jpeglib.h>
 31 
 32 #include <libtracker-common/tracker-common.h>
 33 #include <libtracker-extract/tracker-extract.h>
 34 #include <libtracker-sparql/tracker-sparql.h>
 35 
 36 #include "tracker-main.h"
 37 
 38 #define CM_TO_INCH              0.393700787
 39 
 40 #ifdef HAVE_LIBEXIF
 41 #define EXIF_NAMESPACE          "Exif"
 42 #define EXIF_NAMESPACE_LENGTH   4
 43 #endif /* HAVE_LIBEXIF */
 44 
 45 #ifdef HAVE_EXEMPI
 46 #define XMP_NAMESPACE           "http://ns.adobe.com/xap/1.0/\x00"
 47 #define XMP_NAMESPACE_LENGTH    29
 48 #endif /* HAVE_EXEMPI */
 49 
 50 #ifdef HAVE_LIBIPTCDATA
 51 #define PS3_NAMESPACE           "Photoshop 3.0\0"
 52 #define PS3_NAMESPACE_LENGTH    14
 53 #include <libiptcdata/iptc-jpeg.h>
 54 #endif /* HAVE_LIBIPTCDATA */
 55 
 56 typedef struct {
 57 	const gchar *make;
 58 	const gchar *model;
 59 	const gchar *title;
 60 	const gchar *orientation;
 61 	const gchar *copyright;
 62 	const gchar *white_balance;
 63 	const gchar *fnumber;
 64 	const gchar *flash;
 65 	const gchar *focal_length;
 66 	const gchar *artist;
 67 	const gchar *exposure_time;
 68 	const gchar *iso_speed_ratings;
 69 	const gchar *date;
 70 	const gchar *description;
 71 	const gchar *metering_mode;
 72 	const gchar *creator;
 73 	const gchar *comment;
 74 	const gchar *city;
 75 	const gchar *state;
 76 	const gchar *address;
 77 	const gchar *country;
 78 	const gchar *gps_altitude;
 79 	const gchar *gps_latitude;
 80 	const gchar *gps_longitude;
 81 	const gchar *gps_direction;
 82 } MergeData;
 83 
 84 struct tej_error_mgr {
 85 	struct jpeg_error_mgr jpeg;
 86 	jmp_buf setjmp_buffer;
 87 };
 88 
 89 static void
 90 extract_jpeg_error_exit (j_common_ptr cinfo)
 91 {
 92 	struct tej_error_mgr *h = (struct tej_error_mgr *) cinfo->err;
 93 	(*cinfo->err->output_message)(cinfo);
 94 	longjmp (h->setjmp_buffer, 1);
 95 }
 96 
 97 static gboolean
 98 guess_dlna_profile (gint          width,
 99                     gint          height,
100                     const gchar **dlna_profile,
101                     const gchar **dlna_mimetype)
102 {
103 	const gchar *profile = NULL;
104 
105 	if (dlna_profile) {
106 		*dlna_profile = NULL;
107 	}
108 
109 	if (dlna_mimetype) {
110 		*dlna_mimetype = NULL;
111 	}
112 
113 	if (width <= 640 && height <= 480) {
114 		profile = "JPEG_SM";
115 	} else if (width <= 1024 && height <= 768) {
116 		profile = "JPEG_MED";
117 	} else if (width <= 4096 && height <= 4096) {
118 		profile = "JPEG_LRG";
119 	}
120 
121 	if (profile) {
122 		if (dlna_profile) {
123 			*dlna_profile = profile;
124 		}
125 
126 		if (dlna_mimetype) {
127 			*dlna_mimetype = "image/jpeg";
128 		}
129 
130 		return TRUE;
131 	}
132 
133 	return FALSE;
134 }
135 
136 G_MODULE_EXPORT gboolean
137 tracker_extract_get_metadata (TrackerExtractInfo *info)
138 {
139 	struct jpeg_decompress_struct cinfo;
140 	struct tej_error_mgr tejerr;
141 	struct jpeg_marker_struct *marker;
142 	TrackerSparqlBuilder *preupdate, *metadata;
143 	TrackerXmpData *xd = NULL;
144 	TrackerExifData *ed = NULL;
145 	TrackerIptcData *id = NULL;
146 	MergeData md = { 0 };
147 	GFile *file;
148 	FILE *f;
149 	goffset size;
150 	gchar *filename, *uri;
151 	gchar *comment = NULL;
152 	const gchar *dlna_profile, *dlna_mimetype, *graph;
153 	GPtrArray *keywords;
154 	gboolean success = TRUE;
155 	GString *where;
156 	guint i;
157 
158 	metadata = tracker_extract_info_get_metadata_builder (info);
159 	preupdate = tracker_extract_info_get_preupdate_builder (info);
160 	graph = tracker_extract_info_get_graph (info);
161 
162 	file = tracker_extract_info_get_file (info);
163 	filename = g_file_get_path (file);
164 
165 	size = tracker_file_get_size (filename);
166 
167 	if (size < 18) {
168 		g_free (filename);
169 		return FALSE;
170 	}
171 
172 	f = tracker_file_open (filename);
173 	g_free (filename);
174 
175 	if (!f) {
176 		return FALSE;
177 	}
178 
179 	uri = g_file_get_uri (file);
180 
181 	tracker_sparql_builder_predicate (metadata, "a");
182 	tracker_sparql_builder_object (metadata, "nfo:Image");
183 	tracker_sparql_builder_predicate (metadata, "a");
184 	tracker_sparql_builder_object (metadata, "nmm:Photo");
185 
186 	cinfo.err = jpeg_std_error (&tejerr.jpeg);
187 	tejerr.jpeg.error_exit = extract_jpeg_error_exit;
188 	if (setjmp (tejerr.setjmp_buffer)) {
189 		success = FALSE;
190 		goto fail;
191 	}
192 
193 	jpeg_create_decompress (&cinfo);
194 
195 	jpeg_save_markers (&cinfo, JPEG_COM, 0xFFFF);
196 	jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xFFFF);
197 	jpeg_save_markers (&cinfo, JPEG_APP0 + 13, 0xFFFF);
198 
199 	jpeg_stdio_src (&cinfo, f);
200 
201 	jpeg_read_header (&cinfo, TRUE);
202 
203 	/* FIXME? It is possible that there are markers after SOS,
204 	 * but there shouldn't be. Should we decompress the whole file?
205 	 *
206 	 * jpeg_start_decompress(&cinfo);
207 	 * jpeg_finish_decompress(&cinfo);
208 	 *
209 	 * jpeg_calc_output_dimensions(&cinfo);
210 	 */
211 
212 	marker = (struct jpeg_marker_struct *) &cinfo.marker_list;
213 
214 	while (marker) {
215 		gchar *str;
216 		gsize len;
217 #ifdef HAVE_LIBIPTCDATA
218 		gsize offset;
219 		guint sublen;
220 #endif /* HAVE_LIBIPTCDATA */
221 
222 		switch (marker->marker) {
223 		case JPEG_COM:
224 			g_free (comment);
225 			comment = g_strndup ((gchar*) marker->data, marker->data_length);
226 			break;
227 
228 		case JPEG_APP0 + 1:
229 			str = (gchar*) marker->data;
230 			len = marker->data_length;
231 
232 #ifdef HAVE_LIBEXIF
233 			if (strncmp (EXIF_NAMESPACE, str, EXIF_NAMESPACE_LENGTH) == 0) {
234 				ed = tracker_exif_new ((guchar *) marker->data, len, uri);
235 			}
236 #endif /* HAVE_LIBEXIF */
237 
238 #ifdef HAVE_EXEMPI
239 			if (strncmp (XMP_NAMESPACE, str, XMP_NAMESPACE_LENGTH) == 0) {
240 				xd = tracker_xmp_new (str + XMP_NAMESPACE_LENGTH,
241 				                      len - XMP_NAMESPACE_LENGTH,
242 				                      uri);
243 			}
244 #endif /* HAVE_EXEMPI */
245 
246 			break;
247 
248 		case JPEG_APP0 + 13:
249 			str = (gchar*) marker->data;
250 			len = marker->data_length;
251 #ifdef HAVE_LIBIPTCDATA
252 			if (len > 0 && strncmp (PS3_NAMESPACE, str, PS3_NAMESPACE_LENGTH) == 0) {
253 				offset = iptc_jpeg_ps3_find_iptc (str, len, &sublen);
pointer targets in passing argument 1 of 'iptc_jpeg_ps3_find_iptc' differ in signedness
(emitted by gcc)
254 if (offset > 0 && sublen > 0) { 255 id = tracker_iptc_new (str + offset, sublen, uri); 256 } 257 } 258 #endif /* HAVE_LIBIPTCDATA */ 259 260 break; 261 262 default: 263 marker = marker->next; 264 continue; 265 } 266 267 marker = marker->next; 268 } 269 270 if (!ed) { 271 ed = g_new0 (TrackerExifData, 1); 272 } 273 274 if (!xd) { 275 xd = g_new0 (TrackerXmpData, 1); 276 } 277 278 if (!id) { 279 id = g_new0 (TrackerIptcData, 1); 280 } 281 282 md.title = tracker_coalesce_strip (4, xd->title, ed->document_name, xd->title2, xd->pdf_title); 283 md.orientation = tracker_coalesce_strip (3, xd->orientation, ed->orientation, id->image_orientation); 284 md.copyright = tracker_coalesce_strip (4, xd->copyright, xd->rights, ed->copyright, id->copyright_notice); 285 md.white_balance = tracker_coalesce_strip (2, xd->white_balance, ed->white_balance); 286 md.fnumber = tracker_coalesce_strip (2, xd->fnumber, ed->fnumber); 287 md.flash = tracker_coalesce_strip (2, xd->flash, ed->flash); 288 md.focal_length = tracker_coalesce_strip (2, xd->focal_length, ed->focal_length); 289 md.artist = tracker_coalesce_strip (3, xd->artist, ed->artist, xd->contributor); 290 md.exposure_time = tracker_coalesce_strip (2, xd->exposure_time, ed->exposure_time); 291 md.iso_speed_ratings = tracker_coalesce_strip (2, xd->iso_speed_ratings, ed->iso_speed_ratings); 292 md.date = tracker_coalesce_strip (5, xd->date, xd->time_original, ed->time, id->date_created, ed->time_original); 293 md.description = tracker_coalesce_strip (2, xd->description, ed->description); 294 md.metering_mode = tracker_coalesce_strip (2, xd->metering_mode, ed->metering_mode); 295 md.city = tracker_coalesce_strip (2, xd->city, id->city); 296 md.state = tracker_coalesce_strip (2, xd->state, id->state); 297 md.address = tracker_coalesce_strip (2, xd->address, id->sublocation); 298 md.country = tracker_coalesce_strip (2, xd->country, id->country_name); 299 300 /* FIXME We are not handling the altitude ref here for xmp */ 301 md.gps_altitude = tracker_coalesce_strip (2, xd->gps_altitude, ed->gps_altitude); 302 md.gps_latitude = tracker_coalesce_strip (2, xd->gps_latitude, ed->gps_latitude); 303 md.gps_longitude = tracker_coalesce_strip (2, xd->gps_longitude, ed->gps_longitude); 304 md.gps_direction = tracker_coalesce_strip (2, xd->gps_direction, ed->gps_direction); 305 md.creator = tracker_coalesce_strip (3, xd->creator, id->byline, id->credit); 306 md.comment = tracker_coalesce_strip (2, comment, ed->user_comment); 307 md.make = tracker_coalesce_strip (2, xd->make, ed->make); 308 md.model = tracker_coalesce_strip (2, xd->model, ed->model); 309 310 /* Prioritize on native dimention in all cases */ 311 tracker_sparql_builder_predicate (metadata, "nfo:width"); 312 tracker_sparql_builder_object_int64 (metadata, cinfo.image_width); 313 314 /* TODO: add ontology and store ed->software */ 315 316 tracker_sparql_builder_predicate (metadata, "nfo:height"); 317 tracker_sparql_builder_object_int64 (metadata, cinfo.image_height); 318 319 if (guess_dlna_profile (cinfo.image_width, cinfo.image_height, &dlna_profile, &dlna_mimetype)) { 320 tracker_sparql_builder_predicate (metadata, "nmm:dlnaProfile"); 321 tracker_sparql_builder_object_string (metadata, dlna_profile); 322 tracker_sparql_builder_predicate (metadata, "nmm:dlnaMime"); 323 tracker_sparql_builder_object_string (metadata, dlna_mimetype); 324 } 325 326 if (id->contact) { 327 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", id->contact); 328 329 tracker_sparql_builder_insert_open (preupdate, NULL); 330 if (graph) { 331 tracker_sparql_builder_graph_open (preupdate, graph); 332 } 333 334 tracker_sparql_builder_subject_iri (preupdate, uri); 335 tracker_sparql_builder_predicate (preupdate, "a"); 336 tracker_sparql_builder_object (preupdate, "nco:Contact"); 337 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 338 tracker_sparql_builder_object_unvalidated (preupdate, id->contact); 339 340 if (graph) { 341 tracker_sparql_builder_graph_close (preupdate); 342 } 343 tracker_sparql_builder_insert_close (preupdate); 344 345 tracker_sparql_builder_predicate (metadata, "nco:representative"); 346 tracker_sparql_builder_object_iri (metadata, uri); 347 g_free (uri); 348 } 349 350 keywords = g_ptr_array_new (); 351 352 if (xd->keywords) { 353 tracker_keywords_parse (keywords, xd->keywords); 354 } 355 356 if (xd->pdf_keywords) { 357 tracker_keywords_parse (keywords, xd->pdf_keywords); 358 } 359 360 if (xd->subject) { 361 tracker_keywords_parse (keywords, xd->subject); 362 } 363 364 if (xd->publisher) { 365 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", xd->publisher); 366 367 tracker_sparql_builder_insert_open (preupdate, NULL); 368 if (graph) { 369 tracker_sparql_builder_graph_open (preupdate, graph); 370 } 371 372 tracker_sparql_builder_subject_iri (preupdate, uri); 373 tracker_sparql_builder_predicate (preupdate, "a"); 374 tracker_sparql_builder_object (preupdate, "nco:Contact"); 375 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 376 tracker_sparql_builder_object_unvalidated (preupdate, xd->publisher); 377 378 if (graph) { 379 tracker_sparql_builder_graph_close (preupdate); 380 } 381 tracker_sparql_builder_insert_close (preupdate); 382 383 tracker_sparql_builder_predicate (metadata, "nco:publisher"); 384 tracker_sparql_builder_object_iri (metadata, uri); 385 g_free (uri); 386 } 387 388 if (xd->type) { 389 tracker_sparql_builder_predicate (metadata, "dc:type"); 390 tracker_sparql_builder_object_unvalidated (metadata, xd->type); 391 } 392 393 if (xd->rating) { 394 tracker_sparql_builder_predicate (metadata, "nao:numericRating"); 395 tracker_sparql_builder_object_unvalidated (metadata, xd->rating); 396 } 397 398 if (xd->format) { 399 tracker_sparql_builder_predicate (metadata, "dc:format"); 400 tracker_sparql_builder_object_unvalidated (metadata, xd->format); 401 } 402 403 if (xd->identifier) { 404 tracker_sparql_builder_predicate (metadata, "dc:indentifier"); 405 tracker_sparql_builder_object_unvalidated (metadata, xd->identifier); 406 } 407 408 if (xd->source) { 409 tracker_sparql_builder_predicate (metadata, "dc:source"); 410 tracker_sparql_builder_object_unvalidated (metadata, xd->source); 411 } 412 413 if (xd->language) { 414 tracker_sparql_builder_predicate (metadata, "dc:language"); 415 tracker_sparql_builder_object_unvalidated (metadata, xd->language); 416 } 417 418 if (xd->relation) { 419 tracker_sparql_builder_predicate (metadata, "dc:relation"); 420 tracker_sparql_builder_object_unvalidated (metadata, xd->relation); 421 } 422 423 if (xd->coverage) { 424 tracker_sparql_builder_predicate (metadata, "dc:coverage"); 425 tracker_sparql_builder_object_unvalidated (metadata, xd->coverage); 426 } 427 428 if (xd->license) { 429 tracker_sparql_builder_predicate (metadata, "nie:license"); 430 tracker_sparql_builder_object_unvalidated (metadata, xd->license); 431 } 432 433 if (xd->regions) { 434 tracker_xmp_apply_regions (preupdate, metadata, graph, xd); 435 } 436 437 if (id->keywords) { 438 tracker_keywords_parse (keywords, id->keywords); 439 } 440 441 where = g_string_new (""); 442 443 for (i = 0; i < keywords->len; i++) { 444 gchar *p, *escaped, *var; 445 446 p = g_ptr_array_index (keywords, i); 447 escaped = tracker_sparql_escape_string (p); 448 var = g_strdup_printf ("tag%d", i + 1); 449 450 /* ensure tag with specified label exists */ 451 tracker_sparql_builder_append (preupdate, "INSERT { "); 452 453 if (graph) { 454 tracker_sparql_builder_append (preupdate, "GRAPH <"); 455 tracker_sparql_builder_append (preupdate, graph); 456 tracker_sparql_builder_append (preupdate, "> { "); 457 } 458 459 tracker_sparql_builder_append (preupdate, 460 "_:tag a nao:Tag ; nao:prefLabel \""); 461 tracker_sparql_builder_append (preupdate, escaped); 462 tracker_sparql_builder_append (preupdate, "\""); 463 464 if (graph) { 465 tracker_sparql_builder_append (preupdate, " } "); 466 } 467 468 tracker_sparql_builder_append (preupdate, " }\n"); 469 tracker_sparql_builder_append (preupdate, 470 "WHERE { FILTER (NOT EXISTS { " 471 "?tag a nao:Tag ; nao:prefLabel \""); 472 tracker_sparql_builder_append (preupdate, escaped); 473 tracker_sparql_builder_append (preupdate, 474 "\" }) }\n"); 475 476 /* associate file with tag */ 477 tracker_sparql_builder_predicate (metadata, "nao:hasTag"); 478 tracker_sparql_builder_object_variable (metadata, var); 479 480 g_string_append_printf (where, "?%s a nao:Tag ; nao:prefLabel \"%s\" .\n", var, escaped); 481 482 g_free (var); 483 g_free (escaped); 484 g_free (p); 485 } 486 g_ptr_array_free (keywords, TRUE); 487 488 tracker_extract_info_set_where_clause (info, where->str); 489 g_string_free (where, TRUE); 490 491 if (md.make || md.model) { 492 gchar *equip_uri; 493 494 equip_uri = tracker_sparql_escape_uri_printf ("urn:equipment:%s:%s:", 495 md.make ? md.make : "", 496 md.model ? md.model : ""); 497 498 tracker_sparql_builder_insert_open (preupdate, NULL); 499 if (graph) { 500 tracker_sparql_builder_graph_open (preupdate, graph); 501 } 502 503 tracker_sparql_builder_subject_iri (preupdate, equip_uri); 504 tracker_sparql_builder_predicate (preupdate, "a"); 505 tracker_sparql_builder_object (preupdate, "nfo:Equipment"); 506 507 if (md.make) { 508 tracker_sparql_builder_predicate (preupdate, "nfo:manufacturer"); 509 tracker_sparql_builder_object_unvalidated (preupdate, md.make); 510 } 511 if (md.model) { 512 tracker_sparql_builder_predicate (preupdate, "nfo:model"); 513 tracker_sparql_builder_object_unvalidated (preupdate, md.model); 514 } 515 516 if (graph) { 517 tracker_sparql_builder_graph_close (preupdate); 518 } 519 tracker_sparql_builder_insert_close (preupdate); 520 521 tracker_sparql_builder_predicate (metadata, "nfo:equipment"); 522 tracker_sparql_builder_object_iri (metadata, equip_uri); 523 g_free (equip_uri); 524 } 525 526 tracker_guarantee_title_from_file (metadata, 527 "nie:title", 528 md.title, 529 uri, 530 NULL); 531 532 if (md.orientation) { 533 tracker_sparql_builder_predicate (metadata, "nfo:orientation"); 534 tracker_sparql_builder_object (metadata, md.orientation); 535 } 536 537 if (md.copyright) { 538 tracker_sparql_builder_predicate (metadata, "nie:copyright"); 539 tracker_sparql_builder_object_unvalidated (metadata, md.copyright); 540 } 541 542 if (md.white_balance) { 543 tracker_sparql_builder_predicate (metadata, "nmm:whiteBalance"); 544 tracker_sparql_builder_object (metadata, md.white_balance); 545 } 546 547 if (md.fnumber) { 548 gdouble value; 549 550 value = g_strtod (md.fnumber, NULL); 551 tracker_sparql_builder_predicate (metadata, "nmm:fnumber"); 552 tracker_sparql_builder_object_double (metadata, value); 553 } 554 555 if (md.flash) { 556 tracker_sparql_builder_predicate (metadata, "nmm:flash"); 557 tracker_sparql_builder_object (metadata, md.flash); 558 } 559 560 if (md.focal_length) { 561 gdouble value; 562 563 value = g_strtod (md.focal_length, NULL); 564 tracker_sparql_builder_predicate (metadata, "nmm:focalLength"); 565 tracker_sparql_builder_object_double (metadata, value); 566 } 567 568 if (md.artist) { 569 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", md.artist); 570 571 tracker_sparql_builder_insert_open (preupdate, NULL); 572 if (graph) { 573 tracker_sparql_builder_graph_open (preupdate, graph); 574 } 575 576 tracker_sparql_builder_subject_iri (preupdate, uri); 577 tracker_sparql_builder_predicate (preupdate, "a"); 578 tracker_sparql_builder_object (preupdate, "nco:Contact"); 579 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 580 tracker_sparql_builder_object_unvalidated (preupdate, md.artist); 581 582 if (graph) { 583 tracker_sparql_builder_graph_close (preupdate); 584 } 585 tracker_sparql_builder_insert_close (preupdate); 586 587 tracker_sparql_builder_predicate (metadata, "nco:contributor"); 588 tracker_sparql_builder_object_iri (metadata, uri); 589 g_free (uri); 590 } 591 592 if (md.exposure_time) { 593 gdouble value; 594 595 value = g_strtod (md.exposure_time, NULL); 596 tracker_sparql_builder_predicate (metadata, "nmm:exposureTime"); 597 tracker_sparql_builder_object_double (metadata, value); 598 } 599 600 if (md.iso_speed_ratings) { 601 gdouble value; 602 603 value = g_strtod (md.iso_speed_ratings, NULL); 604 tracker_sparql_builder_predicate (metadata, "nmm:isoSpeed"); 605 tracker_sparql_builder_object_double (metadata, value); 606 } 607 608 tracker_guarantee_date_from_file_mtime (metadata, 609 "nie:contentCreated", 610 md.date, 611 uri); 612 613 if (md.description) { 614 tracker_sparql_builder_predicate (metadata, "nie:description"); 615 tracker_sparql_builder_object_unvalidated (metadata, md.description); 616 } 617 618 if (md.metering_mode) { 619 tracker_sparql_builder_predicate (metadata, "nmm:meteringMode"); 620 tracker_sparql_builder_object (metadata, md.metering_mode); 621 } 622 623 if (md.creator) { 624 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", md.creator); 625 626 tracker_sparql_builder_insert_open (preupdate, NULL); 627 if (graph) { 628 tracker_sparql_builder_graph_open (preupdate, graph); 629 } 630 631 tracker_sparql_builder_subject_iri (preupdate, uri); 632 tracker_sparql_builder_predicate (preupdate, "a"); 633 tracker_sparql_builder_object (preupdate, "nco:Contact"); 634 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 635 tracker_sparql_builder_object_unvalidated (preupdate, md.creator); 636 637 if (graph) { 638 tracker_sparql_builder_graph_close (preupdate); 639 } 640 tracker_sparql_builder_insert_close (preupdate); 641 642 /* NOTE: We only have affiliation with 643 * nco:PersonContact and we are using 644 * nco:Contact here. 645 */ 646 647 /* if (id->byline_title) { */ 648 /* tracker_sparql_builder_insert_open (preupdate, NULL); */ 649 650 /* tracker_sparql_builder_subject (preupdate, "_:affiliation_by_line"); */ 651 /* tracker_sparql_builder_predicate (preupdate, "a"); */ 652 /* tracker_sparql_builder_object (preupdate, "nco:Affiliation"); */ 653 654 /* tracker_sparql_builder_predicate (preupdate, "nco:title"); */ 655 /* tracker_sparql_builder_object_unvalidated (preupdate, id->byline_title); */ 656 657 /* tracker_sparql_builder_insert_close (preupdate); */ 658 659 /* tracker_sparql_builder_predicate (preupdate, "a"); */ 660 /* tracker_sparql_builder_object (preupdate, "nco:Contact"); */ 661 /* tracker_sparql_builder_predicate (preupdate, "nco:hasAffiliation"); */ 662 /* tracker_sparql_builder_object (preupdate, "_:affiliation_by_line"); */ 663 /* } */ 664 665 tracker_sparql_builder_predicate (metadata, "nco:creator"); 666 tracker_sparql_builder_object_iri (metadata, uri); 667 g_free (uri); 668 } 669 670 if (md.comment) { 671 tracker_sparql_builder_predicate (metadata, "nie:comment"); 672 tracker_sparql_builder_object_unvalidated (metadata, md.comment); 673 } 674 675 if (md.address || md.state || md.country || md.city || 676 md.gps_altitude || md.gps_latitude || md.gps_longitude) { 677 678 tracker_sparql_builder_predicate (metadata, "slo:location"); 679 680 tracker_sparql_builder_object_blank_open (metadata); /* GeoPoint */ 681 tracker_sparql_builder_predicate (metadata, "a"); 682 tracker_sparql_builder_object (metadata, "slo:GeoLocation"); 683 684 if (md.address || md.state || md.country || md.city) { 685 gchar *addruri; 686 687 addruri = tracker_sparql_get_uuid_urn (); 688 689 tracker_sparql_builder_predicate (metadata, "slo:postalAddress"); 690 tracker_sparql_builder_object_iri (metadata, addruri); 691 692 tracker_sparql_builder_insert_open (preupdate, NULL); 693 if (graph) { 694 tracker_sparql_builder_graph_open (preupdate, graph); 695 } 696 697 tracker_sparql_builder_subject_iri (preupdate, addruri); 698 699 g_free (addruri); 700 701 tracker_sparql_builder_predicate (preupdate, "a"); 702 tracker_sparql_builder_object (preupdate, "nco:PostalAddress"); 703 704 if (md.address) { 705 tracker_sparql_builder_predicate (preupdate, "nco:streetAddress"); 706 tracker_sparql_builder_object_unvalidated (preupdate, md.address); 707 } 708 709 if (md.state) { 710 tracker_sparql_builder_predicate (preupdate, "nco:region"); 711 tracker_sparql_builder_object_unvalidated (preupdate, md.state); 712 } 713 714 if (md.city) { 715 tracker_sparql_builder_predicate (preupdate, "nco:locality"); 716 tracker_sparql_builder_object_unvalidated (preupdate, md.city); 717 } 718 719 if (md.country) { 720 tracker_sparql_builder_predicate (preupdate, "nco:country"); 721 tracker_sparql_builder_object_unvalidated (preupdate, md.country); 722 } 723 724 if (graph) { 725 tracker_sparql_builder_graph_close (preupdate); 726 } 727 tracker_sparql_builder_insert_close (preupdate); 728 } 729 730 if (md.gps_altitude) { 731 tracker_sparql_builder_predicate (metadata, "slo:altitude"); 732 tracker_sparql_builder_object_unvalidated (metadata, md.gps_altitude); 733 } 734 735 if (md.gps_latitude) { 736 tracker_sparql_builder_predicate (metadata, "slo:latitude"); 737 tracker_sparql_builder_object_unvalidated (metadata, md.gps_latitude); 738 } 739 740 if (md.gps_longitude) { 741 tracker_sparql_builder_predicate (metadata, "slo:longitude"); 742 tracker_sparql_builder_object_unvalidated (metadata, md.gps_longitude); 743 } 744 745 tracker_sparql_builder_object_blank_close (metadata); /* GeoLocation */ 746 } 747 748 if (md.gps_direction) { 749 tracker_sparql_builder_predicate (metadata, "nfo:heading"); 750 tracker_sparql_builder_object_unvalidated (metadata, md.gps_direction); 751 } 752 753 if (cinfo.density_unit != 0 || ed->x_resolution) { 754 gdouble value; 755 756 if (cinfo.density_unit == 0) { 757 if (ed->resolution_unit != 3) 758 value = g_strtod (ed->x_resolution, NULL); 759 else 760 value = g_strtod (ed->x_resolution, NULL) * CM_TO_INCH; 761 } else { 762 if (cinfo.density_unit == 1) 763 value = cinfo.X_density; 764 else 765 value = cinfo.X_density * CM_TO_INCH; 766 } 767 768 tracker_sparql_builder_predicate (metadata, "nfo:horizontalResolution"); 769 tracker_sparql_builder_object_double (metadata, value); 770 } 771 772 if (cinfo.density_unit != 0 || ed->y_resolution) { 773 gdouble value; 774 775 if (cinfo.density_unit == 0) { 776 if (ed->resolution_unit != 3) 777 value = g_strtod (ed->y_resolution, NULL); 778 else 779 value = g_strtod (ed->y_resolution, NULL) * CM_TO_INCH; 780 } else { 781 if (cinfo.density_unit == 1) 782 value = cinfo.Y_density; 783 else 784 value = cinfo.Y_density * CM_TO_INCH; 785 } 786 787 tracker_sparql_builder_predicate (metadata, "nfo:verticalResolution"); 788 tracker_sparql_builder_object_double (metadata, value); 789 } 790 791 jpeg_destroy_decompress (&cinfo); 792 793 tracker_exif_free (ed); 794 tracker_xmp_free (xd); 795 tracker_iptc_free (id); 796 g_free (comment); 797 798 fail: 799 tracker_file_close (f, FALSE); 800 g_free (uri); 801 802 return success; 803 }