Пример #1
0
        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);
        }
Пример #2
0
        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());
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }