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

Location Tool Test ID Function Issue
tracker-extract-tiff.c:326:3 gcc pointer-sign tracker_extract_get_metadata pointer targets in passing argument 1 of 'tracker_iptc_new' 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 #ifndef _GNU_SOURCE
 24 #define _GNU_SOURCE
 25 #endif
 26 
 27 #include <errno.h>
 28 #include <fcntl.h>
 29 #include <string.h>
 30 #include <sys/types.h>
 31 #include <sys/stat.h>
 32 #include <unistd.h>
 33 
 34 #include <glib/gstdio.h>
 35 
 36 #include <tiffio.h>
 37 #include <libtracker-common/tracker-common.h>
 38 #include <libtracker-extract/tracker-extract.h>
 39 
 40 #define CM_TO_INCH          0.393700787
 41 
 42 typedef enum {
 43 	TAG_TYPE_UNDEFINED = 0,
 44 	TAG_TYPE_STRING,
 45 	TAG_TYPE_UINT16,
 46 	TAG_TYPE_UINT32,
 47 	TAG_TYPE_DOUBLE,
 48 	TAG_TYPE_C16_UINT16
 49 } TagType;
 50 
 51 typedef struct {
 52 	const gchar *make;
 53 	const gchar *model;
 54 	const gchar *title;
 55 	const gchar *orientation;
 56 	const gchar *copyright;
 57 	const gchar *white_balance;
 58 	const gchar *fnumber;
 59 	const gchar *flash;
 60 	const gchar *focal_length;
 61 	const gchar *artist;
 62 	const gchar *exposure_time;
 63 	const gchar *iso_speed_ratings;
 64 	const gchar *date;
 65 	const gchar *description;
 66 	const gchar *metering_mode;
 67 	const gchar *creator;
 68 	const gchar *x_dimension;
 69 	const gchar *y_dimension;
 70 	const gchar *city;
 71 	const gchar *state;
 72 	const gchar *address;
 73 	const gchar *country;
 74 	const gchar *gps_altitude;
 75 	const gchar *gps_latitude;
 76 	const gchar *gps_longitude;
 77 	const gchar *gps_direction;
 78 } MergeData;
 79 
 80 typedef struct {
 81 	gchar *artist;
 82 	gchar *copyright;
 83 	gchar *date;
 84 	gchar *title;
 85 	gchar *description;
 86 	gchar *width;
 87 	gchar *length;
 88 	gchar *make;
 89 	gchar *model;
 90 	gchar *orientation;
 91 } TiffData;
 92 
 93 static void
 94 tiff_data_free (TiffData *tags)
 95 {
 96 	g_free (tags->artist);
 97 	g_free (tags->copyright);
 98 	g_free (tags->date);
 99 	g_free (tags->title);
100 	g_free (tags->description);
101 	g_free (tags->width);
102 	g_free (tags->length);
103 	g_free (tags->make);
104 	g_free (tags->model);
105 	g_free (tags->orientation);
106 }
107 
108 static gchar *
109 get_flash (TIFF *image)
110 {
111 	guint16 data = 0;
112 
113 	if (TIFFGetField (image, EXIFTAG_FLASH, &data)) {
114 		switch (data) {
115 		case 0x0001:
116 		case 0x0009:
117 		case 0x000D:
118 		case 0x000F:
119 		case 0x0019:
120 		case 0x001D:
121 		case 0x001F:
122 		case 0x0041:
123 		case 0x0045:
124 		case 0x0047:
125 		case 0x0049:
126 		case 0x004D:
127 		case 0x004F:
128 		case 0x0059:
129 		case 0x005F:
130 		case 0x005D:
131 			return g_strdup ("nmm:flash-on");
132 		default:
133 			return g_strdup ("nmm:flash-off");
134 		}
135 	}
136 
137 	return NULL;
138 }
139 
140 static gchar *
141 get_orientation (TIFF *image)
142 {
143 	guint16 data = 0;
144 
145 	if (TIFFGetField (image, TIFFTAG_ORIENTATION, &data)) {
146 		switch (data) {
147 		case 0: return g_strdup ("nfo:orientation-top");
148 		case 1:	return g_strdup ("nfo:orientation-top-mirror");
149 		case 2:	return g_strdup ("nfo:orientation-bottom");
150 		case 3:	return g_strdup ("nfo:orientation-bottom-mirror");
151 		case 4:	return g_strdup ("nfo:orientation-left-mirror");
152 		case 5:	return g_strdup ("nfo:orientation-right");
153 		case 6:	return g_strdup ("nfo:orientation-right-mirror");
154 		case 7:	return g_strdup ("nfo:orientation-left");
155 		}
156 	}
157 
158 	return NULL;
159 }
160 
161 static gchar *
162 get_metering_mode (TIFF *image)
163 {
164 	guint16 data = 0;
165 
166 	if (TIFFGetField (image, EXIFTAG_METERINGMODE, &data)) {
167 		switch (data) {
168 		case 1: return g_strdup ("nmm:metering-mode-average");
169 		case 2: return g_strdup ("nmm:metering-mode-center-weighted-average");
170 		case 3: return g_strdup ("nmm:metering-mode-spot");
171 		case 4: return g_strdup ("nmm:metering-mode-multispot");
172 		case 5: return g_strdup ("nmm:metering-mode-pattern");
173 		case 6: return g_strdup ("nmm:metering-mode-partial");
174 		default: 
175 			return g_strdup ("nmm:metering-mode-other");
176 		}
177 	}
178 
179 	return NULL;
180 }
181 
182 static gchar *
183 get_white_balance (TIFF *image)
184 {
185 	guint16 data = 0;
186 
187 	if (TIFFGetField (image, EXIFTAG_WHITEBALANCE, &data)) {
188 		if (data == 0) {
189 			return g_strdup ("nmm:white-balance-auto");
190 		} else {
191 			return g_strdup ("nmm:white-balance-manual");
192 		}
193 	}
194 
195 	return NULL;
196 }
197 
198 static gchar *
199 tag_to_string (TIFF    *image, 
200                guint    tag,
201                TagType  type)
202 {
203 	switch (type) {
204 	case TAG_TYPE_STRING: {
205 		gchar *data = NULL;
206 
207 		if (TIFFGetField (image, tag, &data)) {
208 			return g_strdup (data);
209 		}
210 		break;
211 	}
212 
213 	case TAG_TYPE_UINT16: {
214 		guint16 data = 0;
215 
216 		if (TIFFGetField (image, tag, &data)) {
217 			return g_strdup_printf ("%i", data);
218 		}
219 		break;
220 	}
221 
222 	case TAG_TYPE_UINT32: {
223 		guint32 data = 0;
224 
225 		if (TIFFGetField (image, tag, &data)) {
226 			return g_strdup_printf ("%i", data);
227 		}
228 		break;
229 	}
230 
231 	case TAG_TYPE_DOUBLE: {
232 		gfloat data = 0;
233 
234 		if (TIFFGetField (image, tag, &data)) {
235 			return g_strdup_printf ("%f", data);
236 		}
237 		break;
238 	}
239 
240 	case TAG_TYPE_C16_UINT16: {
241 		void *data = NULL;
242 		guint16 count = 0;
243 
244 		if (TIFFGetField (image, tag, &count, &data)) {
245 			return g_strdup_printf ("%i", * (guint16*) data);
246 		}
247 		break;
248 	}
249 
250 	default:
251 		break;
252 	}
253 
254 	return NULL;
255 }
256 
257 G_MODULE_EXPORT gboolean
258 tracker_extract_get_metadata (TrackerExtractInfo *info)
259 {
260 	TIFF *image;
261 	TrackerXmpData *xd = NULL;
262 	TrackerIptcData *id = NULL;
263 	TrackerExifData *ed = NULL;
264 	MergeData md = { 0 };
265 	TiffData td = { 0 };
266 	gchar *filename, *uri;
267 	gchar *date;
268 	glong exif_offset;
269 	GPtrArray *keywords;
270 	guint i;
271 	GFile *file;
272 	TrackerSparqlBuilder *metadata, *preupdate;
273 	const gchar *graph;
274 	GString *where;
275 	int fd;
276 
277 #ifdef HAVE_LIBIPTCDATA
278 	gchar *iptc_offset;
279 	guint32 iptc_size;
280 #endif
281 
282 #ifdef HAVE_EXEMPI
283 	gchar *xmp_offset;
284 	guint32 size;
285 #endif /* HAVE_EXEMPI */
286 
287 	file = tracker_extract_info_get_file (info);
288 	filename = g_file_get_path (file);
289 
290 	preupdate = tracker_extract_info_get_preupdate_builder (info);
291 	metadata = tracker_extract_info_get_metadata_builder (info);
292 	graph = tracker_extract_info_get_graph (info);
293 
294 	fd = tracker_file_open_fd (filename);
295 
296 	if (fd == -1) {
297 		g_warning ("Could not open tiff file '%s': %s\n",
298 		           filename,
299 		           g_strerror (errno));
300 		g_free (filename);
301 		return FALSE;
302 	}	
303 
304 	if ((image = TIFFFdOpen (fd, filename, "r")) == NULL){
305 		g_warning ("Could not open image:'%s'\n", filename);
306 		g_free (filename);
307 		close (fd);
308 		return FALSE;
309 	}
310 
311 	tracker_sparql_builder_predicate (metadata, "a");
312 	tracker_sparql_builder_object (metadata, "nfo:Image");
313 	tracker_sparql_builder_object (metadata, "nmm:Photo");
314 
315 	uri = g_file_get_uri (file);
316 
317 #ifdef HAVE_LIBIPTCDATA
318 	if (TIFFGetField (image, 
319 	                  TIFFTAG_RICHTIFFIPTC, 
320 	                  &iptc_size, 
321 	                  &iptc_offset)) {
322 		if (TIFFIsByteSwapped(image) != 0) {
323 			TIFFSwabArrayOfLong((uint32*) iptc_offset, 
324 			                    (unsigned long) iptc_size);
325 		}
326 		id = tracker_iptc_new (iptc_offset, 4 * iptc_size, uri);
pointer targets in passing argument 1 of 'tracker_iptc_new' differ in signedness
(emitted by gcc)
327 } 328 #endif /* HAVE_LIBIPTCDATA */ 329 330 if (!id) { 331 id = g_new0 (TrackerIptcData, 1); 332 } 333 334 /* FIXME There are problems between XMP data embedded with different tools 335 due to bugs in the original spec (type) */ 336 #ifdef HAVE_EXEMPI 337 if (TIFFGetField (image, TIFFTAG_XMLPACKET, &size, &xmp_offset)) { 338 xd = tracker_xmp_new (xmp_offset, size, uri); 339 } 340 #endif /* HAVE_EXEMPI */ 341 342 if (!xd) { 343 xd = g_new0 (TrackerXmpData, 1); 344 } 345 346 ed = g_new0 (TrackerExifData, 1); 347 348 /* Get Tiff specifics */ 349 td.width = tag_to_string (image, TIFFTAG_IMAGEWIDTH, TAG_TYPE_UINT32); 350 td.length = tag_to_string (image, TIFFTAG_IMAGELENGTH, TAG_TYPE_UINT32); 351 td.artist = tag_to_string (image, TIFFTAG_ARTIST, TAG_TYPE_STRING); 352 td.copyright = tag_to_string (image, TIFFTAG_COPYRIGHT, TAG_TYPE_STRING); 353 354 date = tag_to_string (image, TIFFTAG_DATETIME, TAG_TYPE_STRING); 355 td.date = tracker_date_guess (date); 356 g_free (date); 357 358 td.title = tag_to_string (image, TIFFTAG_DOCUMENTNAME, TAG_TYPE_STRING); 359 td.description = tag_to_string (image, TIFFTAG_IMAGEDESCRIPTION, TAG_TYPE_STRING); 360 td.make = tag_to_string (image, TIFFTAG_MAKE, TAG_TYPE_STRING); 361 td.model = tag_to_string (image, TIFFTAG_MODEL, TAG_TYPE_STRING); 362 td.orientation = get_orientation (image); 363 364 /* Get Exif specifics */ 365 if (TIFFGetField (image, TIFFTAG_EXIFIFD, &exif_offset)) { 366 if (TIFFReadEXIFDirectory (image, exif_offset)) { 367 ed->exposure_time = tag_to_string (image, EXIFTAG_EXPOSURETIME, TAG_TYPE_DOUBLE); 368 ed->fnumber = tag_to_string (image, EXIFTAG_FNUMBER, TAG_TYPE_DOUBLE); 369 ed->iso_speed_ratings = tag_to_string (image, EXIFTAG_ISOSPEEDRATINGS, TAG_TYPE_C16_UINT16); 370 date = tag_to_string (image, EXIFTAG_DATETIMEORIGINAL, TAG_TYPE_STRING); 371 ed->time_original = tracker_date_guess (date); 372 g_free (date); 373 374 ed->metering_mode = get_metering_mode (image); 375 ed->flash = get_flash (image); 376 ed->focal_length = tag_to_string (image, EXIFTAG_DATETIMEORIGINAL, TAG_TYPE_DOUBLE); 377 ed->white_balance = get_white_balance (image); 378 /* ed->software = tag_to_string (image, EXIFTAG_SOFTWARE, TAG_TYPE_STRING); */ 379 } 380 } 381 382 TIFFClose (image); 383 g_free (filename); 384 385 md.title = tracker_coalesce_strip (5, xd->title, xd->pdf_title, td.title, ed->document_name, xd->title2); 386 md.orientation = tracker_coalesce_strip (4, xd->orientation, td.orientation, ed->orientation, id->image_orientation); 387 md.copyright = tracker_coalesce_strip (4, xd->rights, td.copyright, ed->copyright, id->copyright_notice); 388 md.white_balance = tracker_coalesce_strip (2, xd->white_balance, ed->white_balance); 389 md.fnumber = tracker_coalesce_strip (2, xd->fnumber, ed->fnumber); 390 md.flash = tracker_coalesce_strip (2, xd->flash, ed->flash); 391 md.focal_length = tracker_coalesce_strip (2, xd->focal_length, ed->focal_length); 392 md.artist = tracker_coalesce_strip (4, xd->artist, td.artist, ed->artist, xd->contributor); 393 md.exposure_time = tracker_coalesce_strip (2, xd->exposure_time, ed->exposure_time); 394 md.iso_speed_ratings = tracker_coalesce_strip (2, xd->iso_speed_ratings, ed->iso_speed_ratings); 395 md.date = tracker_coalesce_strip (6, xd->date, xd->time_original, td.date, ed->time, id->date_created, ed->time_original); 396 md.description = tracker_coalesce_strip (3, xd->description, td.description, ed->description); 397 md.metering_mode = tracker_coalesce_strip (2, xd->metering_mode, ed->metering_mode); 398 md.city = tracker_coalesce_strip (2, xd->city, id->city); 399 md.state = tracker_coalesce_strip (2, xd->state, id->state); 400 md.address = tracker_coalesce_strip (2, xd->address, id->sublocation); 401 md.country = tracker_coalesce_strip (2, xd->country, id->country_name); 402 403 /* FIXME We are not handling the altitude ref here for xmp */ 404 md.gps_altitude = tracker_coalesce_strip (2, xd->gps_altitude, ed->gps_altitude); 405 md.gps_latitude = tracker_coalesce_strip (2, xd->gps_latitude, ed->gps_latitude); 406 md.gps_longitude = tracker_coalesce_strip (2, xd->gps_longitude, ed->gps_longitude); 407 md.gps_direction = tracker_coalesce_strip (2, xd->gps_direction, ed->gps_direction); 408 md.creator = tracker_coalesce_strip (3, xd->creator, id->byline, id->credit); 409 md.x_dimension = tracker_coalesce_strip (2, td.width, ed->x_dimension); 410 md.y_dimension = tracker_coalesce_strip (2, td.length, ed->y_dimension); 411 md.make = tracker_coalesce_strip (3, xd->make, td.make, ed->make); 412 md.model = tracker_coalesce_strip (3, xd->model, td.model, ed->model); 413 414 keywords = g_ptr_array_new (); 415 416 if (ed->user_comment) { 417 tracker_sparql_builder_predicate (metadata, "nie:comment"); 418 tracker_sparql_builder_object_unvalidated (metadata, ed->user_comment); 419 } 420 421 if (md.x_dimension) { 422 tracker_sparql_builder_predicate (metadata, "nfo:width"); 423 tracker_sparql_builder_object_unvalidated (metadata, md.x_dimension); 424 } 425 426 if (md.y_dimension) { 427 tracker_sparql_builder_predicate (metadata, "nfo:height"); 428 tracker_sparql_builder_object_unvalidated (metadata, md.y_dimension); 429 } 430 431 if (xd->keywords) { 432 tracker_keywords_parse (keywords, xd->keywords); 433 } 434 435 if (xd->pdf_keywords) { 436 tracker_keywords_parse (keywords, xd->pdf_keywords); 437 } 438 439 if (xd->subject) { 440 tracker_keywords_parse (keywords, xd->subject); 441 } 442 443 if (xd->publisher) { 444 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", xd->publisher); 445 446 tracker_sparql_builder_insert_open (preupdate, NULL); 447 if (graph) { 448 tracker_sparql_builder_graph_open (preupdate, graph); 449 } 450 451 tracker_sparql_builder_subject_iri (preupdate, uri); 452 tracker_sparql_builder_predicate (preupdate, "a"); 453 tracker_sparql_builder_object (preupdate, "nco:Contact"); 454 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 455 tracker_sparql_builder_object_unvalidated (preupdate, xd->publisher); 456 457 if (graph) { 458 tracker_sparql_builder_graph_close (preupdate); 459 } 460 tracker_sparql_builder_insert_close (preupdate); 461 462 tracker_sparql_builder_predicate (metadata, "nco:publisher"); 463 tracker_sparql_builder_object_iri (metadata, uri); 464 g_free (uri); 465 } 466 467 if (xd->type) { 468 tracker_sparql_builder_predicate (metadata, "dc:type"); 469 tracker_sparql_builder_object_unvalidated (metadata, xd->type); 470 } 471 472 if (xd->format) { 473 tracker_sparql_builder_predicate (metadata, "dc:format"); 474 tracker_sparql_builder_object_unvalidated (metadata, xd->format); 475 } 476 477 if (xd->identifier) { 478 tracker_sparql_builder_predicate (metadata, "dc:identifier"); 479 tracker_sparql_builder_object_unvalidated (metadata, xd->identifier); 480 } 481 482 if (xd->source) { 483 tracker_sparql_builder_predicate (metadata, "dc:source"); 484 tracker_sparql_builder_object_unvalidated (metadata, xd->source); 485 } 486 487 if (xd->language) { 488 tracker_sparql_builder_predicate (metadata, "dc:language"); 489 tracker_sparql_builder_object_unvalidated (metadata, xd->language); 490 } 491 492 if (xd->relation) { 493 tracker_sparql_builder_predicate (metadata, "dc:relation"); 494 tracker_sparql_builder_object_unvalidated (metadata, xd->relation); 495 } 496 497 if (xd->coverage) { 498 tracker_sparql_builder_predicate (metadata, "dc:coverage"); 499 tracker_sparql_builder_object_unvalidated (metadata, xd->coverage); 500 } 501 502 if (xd->rating) { 503 tracker_sparql_builder_predicate (metadata, "nao:numericRating"); 504 tracker_sparql_builder_object_unvalidated (metadata, xd->rating); 505 } 506 507 if (xd->license) { 508 tracker_sparql_builder_predicate (metadata, "nie:license"); 509 tracker_sparql_builder_object_unvalidated (metadata, xd->license); 510 } 511 512 if (xd->regions) { 513 tracker_xmp_apply_regions (preupdate, metadata, graph, xd); 514 } 515 516 if (md.address || md.state || md.country || md.city || 517 md.gps_altitude || md.gps_latitude || md.gps_longitude) { 518 519 tracker_sparql_builder_predicate (metadata, "slo:location"); 520 521 tracker_sparql_builder_object_blank_open (metadata); /* GeoPoint */ 522 tracker_sparql_builder_predicate (metadata, "a"); 523 tracker_sparql_builder_object (metadata, "slo:GeoLocation"); 524 525 if (md.address || md.state || md.country || md.city) { 526 gchar *addruri; 527 528 addruri = tracker_sparql_get_uuid_urn (); 529 530 tracker_sparql_builder_predicate (metadata, "slo:postalAddress"); 531 tracker_sparql_builder_object_iri (metadata, addruri); 532 533 tracker_sparql_builder_insert_open (preupdate, NULL); 534 if (graph) { 535 tracker_sparql_builder_graph_open (preupdate, graph); 536 } 537 538 tracker_sparql_builder_subject_iri (preupdate, addruri); 539 540 g_free (addruri); 541 542 tracker_sparql_builder_predicate (preupdate, "a"); 543 tracker_sparql_builder_object (preupdate, "nco:PostalAddress"); 544 545 if (md.address) { 546 tracker_sparql_builder_predicate (preupdate, "nco:streetAddress"); 547 tracker_sparql_builder_object_unvalidated (preupdate, md.address); 548 } 549 550 if (md.state) { 551 tracker_sparql_builder_predicate (preupdate, "nco:region"); 552 tracker_sparql_builder_object_unvalidated (preupdate, md.state); 553 } 554 555 if (md.city) { 556 tracker_sparql_builder_predicate (preupdate, "nco:locality"); 557 tracker_sparql_builder_object_unvalidated (preupdate, md.city); 558 } 559 560 if (md.country) { 561 tracker_sparql_builder_predicate (preupdate, "nco:country"); 562 tracker_sparql_builder_object_unvalidated (preupdate, md.country); 563 } 564 565 if (graph) { 566 tracker_sparql_builder_graph_close (preupdate); 567 } 568 tracker_sparql_builder_insert_close (preupdate); 569 } 570 571 if (md.gps_altitude) { 572 tracker_sparql_builder_predicate (metadata, "slo:altitude"); 573 tracker_sparql_builder_object_unvalidated (metadata, md.gps_altitude); 574 } 575 576 if (md.gps_latitude) { 577 tracker_sparql_builder_predicate (metadata, "slo:latitude"); 578 tracker_sparql_builder_object_unvalidated (metadata, md.gps_latitude); 579 } 580 581 if (md.gps_longitude) { 582 tracker_sparql_builder_predicate (metadata, "slo:longitude"); 583 tracker_sparql_builder_object_unvalidated (metadata, md.gps_longitude); 584 } 585 586 tracker_sparql_builder_object_blank_close (metadata); /* GeoLocation */ 587 } 588 589 if (md.gps_direction) { 590 tracker_sparql_builder_predicate (metadata, "nfo:heading"); 591 tracker_sparql_builder_object_unvalidated (metadata, md.gps_direction); 592 } 593 594 if (id->contact) { 595 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", id->contact); 596 597 tracker_sparql_builder_insert_open (preupdate, NULL); 598 if (graph) { 599 tracker_sparql_builder_graph_open (preupdate, graph); 600 } 601 602 tracker_sparql_builder_subject_iri (preupdate, uri); 603 tracker_sparql_builder_predicate (preupdate, "a"); 604 tracker_sparql_builder_object (preupdate, "nco:Contact"); 605 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 606 tracker_sparql_builder_object_unvalidated (preupdate, id->contact); 607 608 if (graph) { 609 tracker_sparql_builder_graph_close (preupdate); 610 } 611 tracker_sparql_builder_insert_close (preupdate); 612 613 tracker_sparql_builder_predicate (metadata, "nco:representative"); 614 tracker_sparql_builder_object_iri (metadata, uri); 615 g_free (uri); 616 } 617 618 if (id->keywords) { 619 tracker_keywords_parse (keywords, id->keywords); 620 } 621 622 where = g_string_new (""); 623 624 for (i = 0; i < keywords->len; i++) { 625 gchar *p, *escaped, *var; 626 627 p = g_ptr_array_index (keywords, i); 628 escaped = tracker_sparql_escape_string (p); 629 var = g_strdup_printf ("tag%d", i + 1); 630 631 /* ensure tag with specified label exists */ 632 tracker_sparql_builder_append (preupdate, "INSERT { "); 633 634 if (graph) { 635 tracker_sparql_builder_append (preupdate, "GRAPH <"); 636 tracker_sparql_builder_append (preupdate, graph); 637 tracker_sparql_builder_append (preupdate, "> { "); 638 } 639 640 tracker_sparql_builder_append (preupdate, 641 "_:tag a nao:Tag ; nao:prefLabel \""); 642 tracker_sparql_builder_append (preupdate, escaped); 643 tracker_sparql_builder_append (preupdate, "\""); 644 645 if (graph) { 646 tracker_sparql_builder_append (preupdate, " } "); 647 } 648 649 tracker_sparql_builder_append (preupdate, " }\n"); 650 tracker_sparql_builder_append (preupdate, 651 "WHERE { FILTER (NOT EXISTS { " 652 "?tag a nao:Tag ; nao:prefLabel \""); 653 tracker_sparql_builder_append (preupdate, escaped); 654 tracker_sparql_builder_append (preupdate, 655 "\" }) }\n"); 656 657 /* associate file with tag */ 658 tracker_sparql_builder_predicate (metadata, "nao:hasTag"); 659 tracker_sparql_builder_object_variable (metadata, var); 660 661 g_string_append_printf (where, "?%s a nao:Tag ; nao:prefLabel \"%s\" .\n", var, escaped); 662 663 g_free (var); 664 g_free (escaped); 665 g_free (p); 666 } 667 g_ptr_array_free (keywords, TRUE); 668 669 tracker_extract_info_set_where_clause (info, where->str); 670 g_string_free (where, TRUE); 671 672 if (md.make || md.model) { 673 gchar *equip_uri; 674 675 equip_uri = tracker_sparql_escape_uri_printf ("urn:equipment:%s:%s:", 676 md.make ? md.make : "", 677 md.model ? md.model : ""); 678 679 tracker_sparql_builder_insert_open (preupdate, NULL); 680 if (graph) { 681 tracker_sparql_builder_graph_open (preupdate, graph); 682 } 683 684 tracker_sparql_builder_subject_iri (preupdate, equip_uri); 685 tracker_sparql_builder_predicate (preupdate, "a"); 686 tracker_sparql_builder_object (preupdate, "nfo:Equipment"); 687 688 if (md.make) { 689 tracker_sparql_builder_predicate (preupdate, "nfo:manufacturer"); 690 tracker_sparql_builder_object_unvalidated (preupdate, md.make); 691 } 692 if (md.model) { 693 tracker_sparql_builder_predicate (preupdate, "nfo:model"); 694 tracker_sparql_builder_object_unvalidated (preupdate, md.model); 695 } 696 697 if (graph) { 698 tracker_sparql_builder_graph_close (preupdate); 699 } 700 tracker_sparql_builder_insert_close (preupdate); 701 702 tracker_sparql_builder_predicate (metadata, "nfo:equipment"); 703 tracker_sparql_builder_object_iri (metadata, equip_uri); 704 g_free (equip_uri); 705 } 706 707 tracker_guarantee_title_from_file (metadata, 708 "nie:title", 709 md.title, 710 uri, 711 NULL); 712 713 if (md.orientation) { 714 tracker_sparql_builder_predicate (metadata, "nfo:orientation"); 715 tracker_sparql_builder_object_unvalidated (metadata, md.orientation); 716 } 717 718 if (md.copyright) { 719 tracker_sparql_builder_predicate (metadata, "nie:copyright"); 720 tracker_sparql_builder_object_unvalidated (metadata, md.copyright); 721 } 722 723 if (md.white_balance) { 724 tracker_sparql_builder_predicate (metadata, "nmm:whiteBalance"); 725 tracker_sparql_builder_object_unvalidated (metadata, md.white_balance); 726 } 727 728 if (md.fnumber) { 729 tracker_sparql_builder_predicate (metadata, "nmm:fnumber"); 730 tracker_sparql_builder_object_unvalidated (metadata, md.fnumber); 731 } 732 733 if (md.flash) { 734 tracker_sparql_builder_predicate (metadata, "nmm:flash"); 735 tracker_sparql_builder_object_unvalidated (metadata, md.flash); 736 } 737 738 if (md.focal_length) { 739 tracker_sparql_builder_predicate (metadata, "nmm:focalLength"); 740 tracker_sparql_builder_object_unvalidated (metadata, md.focal_length); 741 } 742 743 if (md.artist) { 744 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", md.artist); 745 746 tracker_sparql_builder_insert_open (preupdate, NULL); 747 if (graph) { 748 tracker_sparql_builder_graph_open (preupdate, graph); 749 } 750 751 tracker_sparql_builder_subject_iri (preupdate, uri); 752 tracker_sparql_builder_predicate (preupdate, "a"); 753 tracker_sparql_builder_object (preupdate, "nco:Contact"); 754 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 755 tracker_sparql_builder_object_unvalidated (preupdate, md.artist); 756 757 if (graph) { 758 tracker_sparql_builder_graph_close (preupdate); 759 } 760 tracker_sparql_builder_insert_close (preupdate); 761 762 tracker_sparql_builder_predicate (metadata, "nco:contributor"); 763 tracker_sparql_builder_object_iri (metadata, uri); 764 g_free (uri); 765 } 766 767 if (md.exposure_time) { 768 tracker_sparql_builder_predicate (metadata, "nmm:exposureTime"); 769 tracker_sparql_builder_object_unvalidated (metadata, md.exposure_time); 770 } 771 772 if (md.iso_speed_ratings) { 773 tracker_sparql_builder_predicate (metadata, "nmm:isoSpeed"); 774 tracker_sparql_builder_object_unvalidated (metadata, md.iso_speed_ratings); 775 } 776 777 tracker_guarantee_date_from_file_mtime (metadata, 778 "nie:contentCreated", 779 md.date, 780 uri); 781 782 if (md.description) { 783 tracker_sparql_builder_predicate (metadata, "nie:description"); 784 tracker_sparql_builder_object_unvalidated (metadata, md.description); 785 } 786 787 if (md.metering_mode) { 788 tracker_sparql_builder_predicate (metadata, "nmm:meteringMode"); 789 tracker_sparql_builder_object_unvalidated (metadata, md.metering_mode); 790 } 791 792 if (md.creator) { 793 gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", md.creator); 794 795 tracker_sparql_builder_insert_open (preupdate, NULL); 796 if (graph) { 797 tracker_sparql_builder_graph_open (preupdate, graph); 798 } 799 800 tracker_sparql_builder_subject_iri (preupdate, uri); 801 tracker_sparql_builder_predicate (preupdate, "a"); 802 tracker_sparql_builder_object (preupdate, "nco:Contact"); 803 tracker_sparql_builder_predicate (preupdate, "nco:fullname"); 804 tracker_sparql_builder_object_unvalidated (preupdate, md.creator); 805 806 if (graph) { 807 tracker_sparql_builder_graph_close (preupdate); 808 } 809 tracker_sparql_builder_insert_close (preupdate); 810 811 /* NOTE: We only have affiliation with 812 * nco:PersonContact and we are using 813 * nco:Contact here. 814 */ 815 816 /* if (id->byline_title) { */ 817 /* tracker_sparql_builder_insert_open (preupdate, NULL); */ 818 819 /* tracker_sparql_builder_subject (preupdate, "_:affiliation_by_line"); */ 820 /* tracker_sparql_builder_predicate (preupdate, "a"); */ 821 /* tracker_sparql_builder_object (preupdate, "nco:Affiliation"); */ 822 823 /* tracker_sparql_builder_predicate (preupdate, "nco:title"); */ 824 /* tracker_sparql_builder_object_unvalidated (preupdate, id->byline_title); */ 825 826 /* tracker_sparql_builder_insert_close (preupdate); */ 827 828 /* tracker_sparql_builder_predicate (metadata, "a"); */ 829 /* tracker_sparql_builder_object (metadata, "nco:PersonContact"); */ 830 /* tracker_sparql_builder_predicate (metadata, "nco:hasAffiliation"); */ 831 /* tracker_sparql_builder_object (metadata, "_:affiliation_by_line"); */ 832 /* } */ 833 834 tracker_sparql_builder_predicate (metadata, "nco:creator"); 835 tracker_sparql_builder_object_iri (metadata, uri); 836 g_free (uri); 837 } 838 839 if (ed->x_resolution) { 840 gdouble value; 841 842 value = ed->resolution_unit != 3 ? g_strtod (ed->x_resolution, NULL) : g_strtod (ed->x_resolution, NULL) * CM_TO_INCH; 843 tracker_sparql_builder_predicate (metadata, "nfo:horizontalResolution"); 844 tracker_sparql_builder_object_double (metadata, value); 845 } 846 847 if (ed->y_resolution) { 848 gdouble value; 849 850 value = ed->resolution_unit != 3 ? g_strtod (ed->y_resolution, NULL) : g_strtod (ed->y_resolution, NULL) * CM_TO_INCH; 851 tracker_sparql_builder_predicate (metadata, "nfo:verticalResolution"); 852 tracker_sparql_builder_object_double (metadata, value); 853 } 854 855 tiff_data_free (&td); 856 tracker_exif_free (ed); 857 tracker_xmp_free (xd); 858 tracker_iptc_free (id); 859 g_free (uri); 860 861 return TRUE; 862 }