private static List <byte[]> ExtractBuffers(glTFLoader.Schema.Gltf model, string baseDir) { var buffers = new List <byte[]>(); foreach (var selectedBuffer in model.Buffers) { if (selectedBuffer.Uri.StartsWith("data:") && DataURL.FromUri(selectedBuffer.Uri, out DataURL output)) { if (output.Data.Length != selectedBuffer.ByteLength) { throw new InvalidDataException( string.Format( "The specified length of embedded data chunk ({0}) is not equal to the actual length of the data chunk ({1}).", selectedBuffer.ByteLength, output.Data.Length) ); } buffers.Add(output.Data); } else { // OPEN FILE string additionalFilePath = System.IO.Path.Combine(baseDir, selectedBuffer.Uri); using (var fs = File.Open(additionalFilePath, FileMode.Open)) using (var br = new BinaryReader(fs)) { // ONLY READ SPECIFIED CHUNK SIZE buffers.Add(br.ReadBytes(selectedBuffer.ByteLength)); } } } return(buffers); }
private static MgtfBuffer[] ExtractBuffers(string baseDir, glTFLoader.Schema.Buffer[] buffers) { var result = new List <MgtfBuffer>(); foreach (var selectedBuffer in buffers) { if (selectedBuffer.Uri.StartsWith("data:") && DataURL.FromUri(selectedBuffer.Uri, out DataURL output)) { if (output.Data.Length != selectedBuffer.ByteLength) { throw new InvalidDataException( string.Format( "The specified length of embedded data chunk ({0}) is not equal to the actual length of the data chunk ({1}).", selectedBuffer.ByteLength, output.Data.Length) ); } result.Add( new MgtfBuffer { Data = output.Data, } ); } else { // OPEN FILE string additionalFilePath = System.IO.Path.Combine(baseDir, selectedBuffer.Uri); using (var fs = File.Open(additionalFilePath, FileMode.Open)) using (var br = new BinaryReader(fs)) { // ONLY READ SPECIFIED CHUNK SIZE result.Add( new MgtfBuffer { Data = br.ReadBytes(selectedBuffer.ByteLength) } ); } } } return(result.ToArray()); }
private MgtfImage[] ExtractImages(string baseDir, Image[] images, BufferView[] bufferViews) { var count = images != null ? images.Length : 0; var output = new MgtfImage[count]; for (var i = 0; i < count; i += 1) { var current = images[i]; byte[] src = null; ulong srcOffset = 0; ulong srcLength = 0UL; int? bufferRef = null; string userDefMimeType = null; if (current.BufferView.HasValue) { var view = bufferViews[current.BufferView.Value]; src = null; bufferRef = view.Buffer; srcOffset = (ulong)view.ByteOffset; srcLength = (ulong)view.ByteLength; } else if (!string.IsNullOrWhiteSpace(current.Uri)) { if (DataURL.FromUri(current.Uri, out DataURL urlData)) { userDefMimeType = urlData.MediaType; src = urlData.Data; srcOffset = 0UL; srcLength = (ulong)urlData.Data.Length; } else { // OPEN FILE userDefMimeType = Path.GetExtension(current.Uri).ToUpperInvariant(); string additionalFilePath = System.IO.Path.Combine(baseDir, current.Uri); using (var fs = File.Open(additionalFilePath, FileMode.Open)) using (var ms = new MemoryStream()) { fs.CopyTo(ms); src = ms.ToArray(); srcOffset = 0UL; srcLength = (ulong)src.Length; } } } MgtfImageMimeType mimeType = current.MimeType.HasValue ? GetImageTypeFromJSON(current.MimeType.Value) : GetImageTypeFromStr(userDefMimeType); var temp = new MgtfImage { Name = current.Name, MimeType = mimeType, Source = src, Buffer = bufferRef, SrcOffset = srcOffset, SrcLength = srcLength, }; output[i] = temp; } return(output); }
public static bool FromUri(string uri, out DataURL output) { // https://tools.ietf.org/html/rfc2397 // BASE64 // data:[< mediatype >][; base64],< data > // // dataurl:= "data:"[mediatype][";base64"] "," data // mediatype := [type "/" subtype] * (";" parameter ) // data:= *urlchar // parameter:= attribute "=" value const string DATA_PREFIX = "data:"; if (!uri.StartsWith(DATA_PREFIX)) { output = null; return(false); } var endOfPrefix = uri.IndexOf(','); if (endOfPrefix <= -1) { output = null; return(false); } // DON'T include the comma on end var mediaTypeToken = uri.Substring(DATA_PREFIX.Length, endOfPrefix - DATA_PREFIX.Length); var parameters = mediaTypeToken.Split(new char[] { ';' }, StringSplitOptions.None); const string PLAIN_TEXT = "text/plain"; var mediaType = (parameters.Length > 0 && string.IsNullOrEmpty(parameters[0])) ? PLAIN_TEXT : parameters[0]; const string BASE_64_FLAG = "base64"; var useBase64 = (parameters.Length > 0 && parameters[parameters.Length - 1] == BASE_64_FLAG); // LOOK FOR CHARSET string textCharsetString = "US-ASCII"; const string CHARSET_TOKEN = "charset"; for (var i = 1; i < parameters.Length; i += 1) { if (parameters[i].Contains("=")) { var paramTokens = parameters[i].Split(new[] { '=' }, StringSplitOptions.None); if (paramTokens.Length == 2 && paramTokens[0] == CHARSET_TOKEN) { textCharsetString = paramTokens[1]; } } } // DEFAULT is text/plain;charset=US-ASCII var dataToken = uri.Substring(endOfPrefix + 1); if (useBase64) { output = new DataURL { MediaType = mediaType, CharSet = textCharsetString, Data = Convert.FromBase64String(dataToken), }; return(true); } else { var encoder = Encoding.GetEncoding(textCharsetString); output = new DataURL { MediaType = mediaType, CharSet = textCharsetString, Data = encoder.GetBytes(dataToken), }; return(true); } }