Exemplo n.º 1
0
        public void EncodeFromRaw()
        {
            const string testImage = "obama-240p.raw";
            var          path      = Path.GetFullPath(Path.Combine(TestImageDirectory, testImage));
            var          imageByte = File.ReadAllBytes(path);

            using var image = ImageHelper.FromRaw(imageByte, 427, 240, 427 * 3, 3, true);

            using var compressionParameters = new CompressionParameters();
            OpenJpeg.SetDefaultEncoderParameters(compressionParameters);
            compressionParameters.TcpNumLayers = 1;
            compressionParameters.CodingParameterDistortionAllocation = 1;

            using var codec = OpenJpeg.CreateCompress(CodecFormat.J2k);

            OpenJpeg.SetInfoHandler(codec, new DelegateHandler <MsgCallback>(MsgInfoCallback), IntPtr.Zero);
            OpenJpeg.SetWarnHandler(codec, new DelegateHandler <MsgCallback>(MsgWarnCallback), IntPtr.Zero);
            OpenJpeg.SetErrorHandler(codec, new DelegateHandler <MsgCallback>(MsgErrorCallback), IntPtr.Zero);

            Assert.True(OpenJpeg.SetupEncoder(codec, compressionParameters, image));

            var bufferLength = imageByte.Length + 1024;
            var outputBuffer = Marshal.AllocHGlobal(bufferLength);

            var buffer = new Buffer
            {
                Data     = outputBuffer,
                Length   = bufferLength,
                Position = 0
            };

            var size     = Marshal.SizeOf(buffer);
            var userData = Marshal.AllocHGlobal(size);

            Marshal.StructureToPtr(buffer, userData, false);

            using var stream = OpenJpeg.StreamCreate((ulong)buffer.Length, false);
            OpenJpeg.StreamSetUserData(stream, userData);
            OpenJpeg.StreamSetUserDataLength(stream, buffer.Length);
            OpenJpeg.StreamSetWriteFunction(stream, new DelegateHandler <StreamWrite>(StreamWriteCallback));
            OpenJpeg.StreamSetReadFunction(stream, new DelegateHandler <StreamRead>(StreamReadCallback));
            OpenJpeg.StreamSetSeekFunction(stream, new DelegateHandler <StreamSeek>(StreamSeekCallback));
            OpenJpeg.StreamSetSkipFunction(stream, new DelegateHandler <StreamSkip>(StreamSkipCallback));

            Assert.True(OpenJpeg.StartCompress(codec, image, stream));
            Assert.True(OpenJpeg.Encode(codec, stream));
            Assert.True(OpenJpeg.EndCompress(codec, stream));

            var outputPath = Path.Combine(ResultDirectory, nameof(this.EncodeFromRaw), $"{Path.GetFileNameWithoutExtension(testImage)}.j2k");

            Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
            var tmp    = Marshal.PtrToStructure <Buffer>(userData);
            var output = new byte[tmp.Position];

            Marshal.Copy(buffer.Data, output, 0, output.Length);
            File.WriteAllBytes(outputPath, output);

            Marshal.FreeHGlobal(outputBuffer);
            Marshal.FreeHGlobal(userData);
        }
Exemplo n.º 2
0
        public void Compress()
        {
            var targets = new[]
            {
                new { Format = CodecFormat.Unknown, FileName = $"{nameof(this.Compress)}.ukn", Result = false },
                new { Format = CodecFormat.J2k, FileName = $"{nameof(this.Compress)}.j2k", Result = true },
                new { Format = CodecFormat.Jp2, FileName = $"{nameof(this.Compress)}.jp2", Result = true },
                new { Format = CodecFormat.Jpp, FileName = $"{nameof(this.Compress)}.jpp", Result = false },
                new { Format = CodecFormat.Jpt, FileName = $"{nameof(this.Compress)}.jpt", Result = false },
                new { Format = CodecFormat.Jpx, FileName = $"{nameof(this.Compress)}.jpx", Result = false },
            };

            const int  numCompsMax            = 4;
            const int  codeBlockWidthInitial  = 64;
            const int  codeBlockHeightInitial = 64;
            const int  numComps     = 3;
            const int  imageWidth   = 2000;
            const int  imageHeight  = 2000;
            const int  tileWidth    = 1000;
            const int  tileHeight   = 1000;
            const uint compPrec     = 8;
            const bool irreversible = false;
            const uint offsetX      = 0;
            const uint offsetY      = 0;

            var tilesWidth  = (offsetX + imageWidth + tileWidth - 1) / tileWidth;
            var tilesHeight = (offsetY + imageHeight + tileHeight - 1) / tileHeight;
            var tiles       = tilesWidth * tilesHeight;
            var dataSize    = tileWidth * tileHeight * numComps * (compPrec / 8);

            var data = new byte[dataSize];

            for (var index = 0; index < data.Length; index++)
            {
                data[index] = (byte)(index % byte.MaxValue);
            }

            foreach (var target in targets)
            {
                var codec = OpenJpeg.CreateCompress(target.Format);
                var compressionParameters = new CompressionParameters();
                OpenJpeg.SetDefaultEncoderParameters(compressionParameters);

                compressionParameters.TcpNumLayers = 1;
                compressionParameters.CodingParameterFixedQuality = 1;
                compressionParameters.TcpDistoratio[0]            = 20;
                compressionParameters.CodingParameterTx0          = 0;
                compressionParameters.CodingParameterTy0          = 0;
                compressionParameters.TileSizeOn             = true;
                compressionParameters.CodingParameterTdx     = tileWidth;
                compressionParameters.CodingParameterTdy     = tileHeight;
                compressionParameters.CodeBlockWidthInitial  = codeBlockWidthInitial;
                compressionParameters.CodeBlockHeightInitial = codeBlockHeightInitial;
                compressionParameters.Irreversible           = irreversible;

                var parameters = new ImageComponentParameters[numCompsMax];
                for (var index = 0; index < parameters.Length; index++)
                {
                    parameters[index] = new ImageComponentParameters
                    {
                        Dx        = 1,
                        Dy        = 1,
                        Height    = imageHeight,
                        Width     = imageWidth,
                        Signed    = false,
                        Precision = compPrec,
                        X0        = offsetX,
                        Y0        = offsetY
                    };
                }

                var image = OpenJpeg.ImageTileCreate(numComps, parameters, ColorSpace.Srgb);
                image.X0         = offsetX;
                image.Y0         = offsetY;
                image.X1         = offsetX + imageWidth;
                image.Y1         = offsetY + imageHeight;
                image.ColorSpace = ColorSpace.Srgb;

                Directory.CreateDirectory(ResultDirectory);
                Directory.CreateDirectory(Path.Combine(ResultDirectory, nameof(this.Compress)));
                var path = Path.Combine(ResultDirectory, nameof(this.Compress), target.FileName);

                Assert.True(OpenJpeg.SetupEncoder(codec, compressionParameters, image) == target.Result, $"Failed to invoke {nameof(OpenJpeg.SetupDecoder)} for {target.Format}");
                if (!target.Result)
                {
                    this.DisposeAndCheckDisposedState(image);
                    this.DisposeAndCheckDisposedState(compressionParameters);
                    this.DisposeAndCheckDisposedState(codec);
                    continue;
                }

                var stream = OpenJpeg.StreamCreateDefaultFileStream(path, false);

                OpenJpeg.StartCompress(codec, image, stream);

                for (var i = 0; i < tiles; ++i)
                {
                    var tileY    = (uint)(i / tilesWidth);
                    var tileX    = (uint)(i % tilesHeight);
                    var tileX0   = Math.Max(image.X0, tileX * tileWidth);
                    var tileY0   = Math.Max(image.Y0, tileY * tileHeight);
                    var tileX1   = Math.Min(image.X1, (tileX + 1) * tileWidth);
                    var tileY1   = Math.Min(image.Y1, (tileY + 1) * tileHeight);
                    var tilesize = (tileX1 - tileX0) * (tileY1 - tileY0) * numComps * (compPrec / 8);
                    Assert.True(OpenJpeg.WriteTile(codec, i, data, tilesize, stream), $"Failed to invoke {nameof(OpenJpeg.WriteTile)}");
                }

                OpenJpeg.EndCompress(codec, stream);

                this.DisposeAndCheckDisposedState(stream);
                this.DisposeAndCheckDisposedState(image);
                this.DisposeAndCheckDisposedState(compressionParameters);
                this.DisposeAndCheckDisposedState(codec);
            }
        }