VIOAPI VIO_BOOL input_one_tag( FILE *file, int n_volumes, VIO_Real tag_volume1[], VIO_Real tag_volume2[], VIO_Real *weight, int *structure_id, int *patient_id, VIO_STR *label, VIO_Status *status ) { VIO_BOOL read_one; VIO_Status read_status; read_status = read_one_tag( file, n_volumes, tag_volume1, tag_volume2, weight, structure_id, patient_id, label ); read_one = (read_status == VIO_OK); if( read_status == VIO_END_OF_FILE ) read_status = VIO_OK; if( status != NULL ) *status = read_status; return( read_one ); }
/** * gst_tag_list_from_xmp_buffer: * @buffer: buffer * * Parse a xmp packet into a taglist. * * Returns: new taglist or %NULL, free the list when done * * Since: 0.10.29 */ GstTagList * gst_tag_list_from_xmp_buffer (const GstBuffer * buffer) { GstTagList *list = NULL; const gchar *xps, *xp1, *xp2, *xpe, *ns, *ne; guint len, max_ft_len; gboolean in_tag; gchar *part, *pp; guint i; const gchar *last_tag = NULL; XmpTag *last_xmp_tag = NULL; GSList *pending_tags = NULL; xmp_tags_initialize (); g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL); g_return_val_if_fail (GST_BUFFER_SIZE (buffer) > 0, NULL); xps = (const gchar *) GST_BUFFER_DATA (buffer); len = GST_BUFFER_SIZE (buffer); xpe = &xps[len + 1]; /* check header and footer */ xp1 = g_strstr_len (xps, len, "<?xpacket begin"); if (!xp1) goto missing_header; xp1 = &xp1[strlen ("<?xpacket begin")]; while (*xp1 != '>' && *xp1 != '<' && xp1 < xpe) xp1++; if (*xp1 != '>') goto missing_header; max_ft_len = 1 + strlen ("<?xpacket end=\".\"?>\n"); if (len < max_ft_len) goto missing_footer; GST_DEBUG ("checking footer: [%s]", &xps[len - max_ft_len]); xp2 = g_strstr_len (&xps[len - max_ft_len], max_ft_len, "<?xpacket "); if (!xp2) goto missing_footer; GST_INFO ("xmp header okay"); /* skip > and text until first xml-node */ xp1++; while (*xp1 != '<' && xp1 < xpe) xp1++; /* no tag can be longer that the whole buffer */ part = g_malloc (xp2 - xp1); list = gst_tag_list_new (); /* parse data into a list of nodes */ /* data is between xp1..xp2 */ in_tag = TRUE; ns = ne = xp1; pp = part; while (ne < xp2) { if (in_tag) { ne++; while (ne < xp2 && *ne != '>' && *ne != '<') { if (*ne == '\n' || *ne == '\t' || *ne == ' ') { while (ne < xp2 && (*ne == '\n' || *ne == '\t' || *ne == ' ')) ne++; *pp++ = ' '; } else { *pp++ = *ne++; } } *pp = '\0'; if (*ne != '>') goto broken_xml; /* create node */ /* {XML, ns, ne-ns} */ if (ns[0] != '/') { gchar *as = strchr (part, ' '); /* only log start nodes */ GST_INFO ("xml: %s", part); if (as) { gchar *ae, *d; /* skip ' ' and scan the attributes */ as++; d = ae = as; /* split attr=value pairs */ while (*ae != '\0') { if (*ae == '=') { /* attr/value delimmiter */ d = ae; } else if (*ae == '"') { /* scan values */ gchar *v; ae++; while (*ae != '\0' && *ae != '"') ae++; *d = *ae = '\0'; v = &d[2]; GST_INFO (" : [%s][%s]", as, v); if (!strncmp (as, "xmlns:", 6)) { i = 0; /* we need to rewrite known namespaces to what we use in * tag_matches */ while (ns_match[i].ns_prefix) { if (!strcmp (ns_match[i].ns_uri, v)) break; i++; } if (ns_match[i].ns_prefix) { if (strcmp (ns_map[i].original_ns, &as[6])) { ns_map[i].gstreamer_ns = g_strdup (&as[6]); } } } else { const gchar *gst_tag; XmpTag *xmp_tag = NULL; /* FIXME: eventualy rewrite ns * find ':' * check if ns before ':' is in ns_map and ns_map[i].gstreamer_ns!=NULL * do 2 stage filter in tag_matches */ gst_tag = _xmp_tag_get_mapping_reverse (as, &xmp_tag); if (gst_tag) { PendingXmpTag *ptag; ptag = g_slice_new (PendingXmpTag); ptag->gst_tag = gst_tag; ptag->xmp_tag = xmp_tag; ptag->str = g_strdup (v); pending_tags = g_slist_append (pending_tags, ptag); } } /* restore chars overwritten by '\0' */ *d = '='; *ae = '"'; } else if (*ae == '\0' || *ae == ' ') { /* end of attr/value pair */ as = &ae[1]; } /* to next char if not eos */ if (*ae != '\0') ae++; } } else { /* <dc:type><rdf:Bag><rdf:li>Image</rdf:li></rdf:Bag></dc:type> <dc:creator><rdf:Seq><rdf:li/></rdf:Seq></dc:creator> */ /* FIXME: eventualy rewrite ns */ /* skip rdf tags for now */ if (strncmp (part, "rdf:", 4)) { const gchar *parttag; parttag = _xmp_tag_get_mapping_reverse (part, &last_xmp_tag); if (parttag) { last_tag = parttag; } } } } /* next cycle */ ne++; if (ne < xp2) { if (*ne != '<') in_tag = FALSE; ns = ne; pp = part; } } else { while (ne < xp2 && *ne != '<') { *pp++ = *ne; ne++; } *pp = '\0'; /* create node */ /* {TXT, ns, (ne-ns)-1} */ if (ns[0] != '\n' && &ns[1] <= ne) { /* only log non-newline nodes, we still have to parse them */ GST_INFO ("txt: %s", part); if (last_tag) { PendingXmpTag *ptag; ptag = g_slice_new (PendingXmpTag); ptag->gst_tag = last_tag; ptag->xmp_tag = last_xmp_tag; ptag->str = g_strdup (part); pending_tags = g_slist_append (pending_tags, ptag); } } /* next cycle */ in_tag = TRUE; ns = ne; pp = part; } } while (pending_tags) { PendingXmpTag *ptag = (PendingXmpTag *) pending_tags->data; pending_tags = g_slist_delete_link (pending_tags, pending_tags); read_one_tag (list, ptag->gst_tag, ptag->xmp_tag, ptag->str, &pending_tags); g_free (ptag->str); g_slice_free (PendingXmpTag, ptag); } GST_INFO ("xmp packet parsed, %d entries", gst_structure_n_fields ((GstStructure *) list)); /* free resources */ i = 0; while (ns_map[i].original_ns) { g_free (ns_map[i].gstreamer_ns); i++; } g_free (part); return list; /* Errors */ missing_header: GST_WARNING ("malformed xmp packet header"); return NULL; missing_footer: GST_WARNING ("malformed xmp packet footer"); return NULL; broken_xml: GST_WARNING ("malformed xml tag: %s", part); return NULL; }