├── .gitignore ├── .vscode └── tasks.json ├── Geb.Image.sln ├── README.md ├── examples ├── .vscode │ └── launch.json ├── 1.png ├── 2.png ├── 3.png ├── basic │ ├── basic.csx │ ├── bitmap.csx │ └── resize.csx ├── common.csx └── omnisharp.json ├── license.txt ├── pack ├── gebimage.nuspec └── nugetpack.bat └── src ├── Geb.Image.OpenCV ├── Geb.Image.OpenCV.csproj └── MatClassHelper.cs ├── Geb.Image.Test ├── BitmapTest.cs ├── Geb.Image.Test.csproj ├── ImageResizeTest.cs └── img │ ├── demo-bmp-24.bmp │ └── demo-bmp-big-01.bmp ├── Geb.Image.WinForm ├── BitmapHelper.cs ├── FrmImage.Designer.cs ├── FrmImage.cs ├── FrmImage.resx ├── Geb.Image.WinForm.csproj └── Geb.Image.WinForm.csproj.user └── Geb.Image ├── Common ├── ClassHelper.cs ├── Complex.cs ├── Config.cs ├── ConvolutionKernel.cs ├── Enums.cs ├── FourierTransform.cs ├── ImagePool.cs ├── Matrix.cs ├── MemoryStorage.cs ├── PixelFormat.cs ├── Range.cs └── Structs.cs ├── Formats ├── Bmp │ ├── BmpBitsPerPixel.cs │ ├── BmpCompression.cs │ ├── BmpConstants.cs │ ├── BmpDecoder.cs │ ├── BmpDecoderCore.cs │ ├── BmpEncoder.cs │ ├── BmpEncoderCore.cs │ ├── BmpFileHeader.cs │ ├── BmpFormat.cs │ ├── BmpImageFormatDetector.cs │ └── BmpInfoHeader.cs ├── Configuration.cs ├── Extentions │ ├── AdvancedImageExtensions.cs │ ├── Buffer2DExtensions.cs │ ├── BufferExtensions.cs │ ├── ComparableExtensions.cs │ ├── SimdUtils.cs │ └── StreamExtensions.cs ├── Gif │ ├── DisposalMethod.cs │ ├── FrameDecodingMode.cs │ ├── GifConfigurationModule.cs │ ├── GifConstants.cs │ ├── GifDecoder.cs │ ├── GifDecoderCore.cs │ ├── GifEncoder.cs │ ├── GifEncoderCore.cs │ ├── GifFormat.cs │ ├── GifImageFormatDetector.cs │ ├── IGifDecoderOptions.cs │ ├── IGifEncoderOptions.cs │ ├── LzwDecoder.cs │ ├── LzwEncoder.cs │ ├── README.md │ ├── Sections │ │ ├── GifGraphicControlExtension.cs │ │ ├── GifImageDescriptor.cs │ │ ├── GifLogicalScreenDescriptor.cs │ │ └── IGifExtension.cs │ └── spec-gif89a.txt ├── IConfigurationModule.cs ├── IImageDecoder.cs ├── IImageFormat.cs ├── IImageFormatDetector.cs ├── IImageInfo.cs ├── ImageFormatException.cs ├── ImageFormats.cs ├── ImageInfo.cs ├── Jpeg │ ├── BaseJpegEncoder.cs │ ├── Components │ │ ├── Block8x8.cs │ │ ├── Block8x8F.CopyTo.cs │ │ ├── Block8x8F.Generated.cs │ │ ├── Block8x8F.Generated.tt │ │ ├── Block8x8F.cs │ │ ├── Decoder │ │ │ ├── AdobeMarker.cs │ │ │ ├── ColorConverters │ │ │ │ ├── JpegColorConverter.FromCmyk.cs │ │ │ │ ├── JpegColorConverter.FromGrayScale.cs │ │ │ │ ├── JpegColorConverter.FromRgb.cs │ │ │ │ ├── JpegColorConverter.FromYCbCrBasic.cs │ │ │ │ ├── JpegColorConverter.FromYCbCrSimd.cs │ │ │ │ ├── JpegColorConverter.FromYCbCrSimdAvx2.cs │ │ │ │ ├── JpegColorConverter.FromYccK.cs │ │ │ │ └── JpegColorConverter.cs │ │ │ ├── IJpegComponent.cs │ │ │ ├── IRawJpegData.cs │ │ │ ├── JFifMarker.cs │ │ │ ├── JpegBlockPostProcessor.cs │ │ │ ├── JpegColorSpace.cs │ │ │ ├── JpegComponentPostProcessor.cs │ │ │ ├── JpegImagePostProcessor.cs │ │ │ └── ProfileResolver.cs │ │ ├── Encoder │ │ │ ├── BlockQuad.cs │ │ │ ├── GrayForwardConverter.cs │ │ │ ├── HuffIndex.cs │ │ │ ├── HuffmanLut.cs │ │ │ ├── HuffmanSpec.cs │ │ │ ├── QuantIndex.cs │ │ │ ├── RgbToYCbCrTables.cs │ │ │ └── YCbCrForwardConverter.cs │ │ ├── FastFloatingPointDCT.cs │ │ ├── GenericBlock8x8.Generated.cs │ │ ├── GenericBlock8x8.Generated.tt │ │ ├── GenericBlock8x8.cs │ │ ├── SizeExtensions.cs │ │ └── ZigZag.cs │ ├── IJpegDecoderOptions.cs │ ├── IJpegEncoderOptions.cs │ ├── ImageHolder.cs │ ├── Jpeg12Encoder.cs │ ├── Jpeg16Encoder.cs │ ├── Jpeg8Encoder.cs │ ├── JpegConstants.cs │ ├── JpegDecoder.cs │ ├── JpegEncoder.cs │ ├── JpegFormat.cs │ ├── JpegImageFormatDetector.cs │ ├── JpegSubsample.cs │ └── PdfJsPort │ │ ├── Components │ │ ├── DoubleBufferedStreamReader.cs │ │ ├── FixedByteBuffer256.cs │ │ ├── FixedInt16Buffer18.cs │ │ ├── FixedInt16Buffer256.cs │ │ ├── FixedInt64Buffer18.cs │ │ ├── PdfJsFileMarker.cs │ │ ├── PdfJsFrame.cs │ │ ├── PdfJsFrameComponent.cs │ │ ├── PdfJsHuffmanTable.cs │ │ ├── PdfJsHuffmanTables.cs │ │ └── PdfJsScanDecoder.cs │ │ ├── PdfJsJpegDecoder.cs │ │ └── PdfJsJpegDecoderCore.cs ├── Memory │ ├── ArrayPoolMemoryManager.cs │ ├── BasicArrayBuffer.cs │ ├── BasicByteBuffer.cs │ ├── Buffer2D.cs │ ├── BufferArea.cs │ ├── IBuffer.cs │ ├── IBuffer2D.cs │ ├── IManagedByteBuffer.cs │ ├── MemoryManager.cs │ ├── MemoryManagerExtensions.cs │ └── SimpleGcMemoryManager.cs ├── MetaData │ ├── ImageFrameMetaData.cs │ ├── ImageMetaData.cs │ ├── ImageProperty.cs │ └── Profiles │ │ ├── Exif │ │ ├── ExifDataType.cs │ │ ├── ExifParts.cs │ │ ├── ExifProfile.cs │ │ ├── ExifReader.cs │ │ ├── ExifTag.cs │ │ ├── ExifTagDescriptionAttribute.cs │ │ ├── ExifTags.cs │ │ ├── ExifValue.cs │ │ ├── ExifWriter.cs │ │ └── README.md │ │ └── ICC │ │ ├── Curves │ │ ├── IccCurveSegment.cs │ │ ├── IccFormulaCurveElement.cs │ │ ├── IccOneDimensionalCurve.cs │ │ ├── IccParametricCurve.cs │ │ ├── IccResponseCurve.cs │ │ └── IccSampledCurveElement.cs │ │ ├── DataReader │ │ ├── IccDataReader.Curves.cs │ │ ├── IccDataReader.Lut.cs │ │ ├── IccDataReader.Matrix.cs │ │ ├── IccDataReader.MultiProcessElement.cs │ │ ├── IccDataReader.NonPrimitives.cs │ │ ├── IccDataReader.Primitives.cs │ │ ├── IccDataReader.TagDataEntry.cs │ │ └── IccDataReader.cs │ │ ├── DataWriter │ │ ├── IccDataWriter.Curves.cs │ │ ├── IccDataWriter.Lut.cs │ │ ├── IccDataWriter.Matrix.cs │ │ ├── IccDataWriter.MultiProcessElement.cs │ │ ├── IccDataWriter.NonPrimitives.cs │ │ ├── IccDataWriter.Primitives.cs │ │ ├── IccDataWriter.TagDataEntry.cs │ │ └── IccDataWriter.cs │ │ ├── Enums │ │ ├── IccClutDataType.cs │ │ ├── IccColorSpaceType.cs │ │ ├── IccColorantEncoding.cs │ │ ├── IccCurveMeasurementEncodings.cs │ │ ├── IccCurveSegmentSignature.cs │ │ ├── IccDataType.cs │ │ ├── IccDeviceAttribute.cs │ │ ├── IccFormulaCurveType.cs │ │ ├── IccMeasurementGeometry.cs │ │ ├── IccMultiProcessElementSignature.cs │ │ ├── IccParametricCurveType.cs │ │ ├── IccPrimaryPlatformType.cs │ │ ├── IccProfileClass.cs │ │ ├── IccProfileFlag.cs │ │ ├── IccProfileTag.cs │ │ ├── IccRenderingIntent.cs │ │ ├── IccScreeningFlag.cs │ │ ├── IccScreeningSpotType.cs │ │ ├── IccSignatureName.cs │ │ ├── IccStandardIlluminant.cs │ │ ├── IccStandardObserver.cs │ │ └── IccTypeSignature.cs │ │ ├── Exceptions │ │ └── InvalidIccProfileException.cs │ │ ├── IccProfile.cs │ │ ├── IccProfileHeader.cs │ │ ├── IccReader.cs │ │ ├── IccTagDataEntry.cs │ │ ├── IccWriter.cs │ │ ├── MultiProcessElements │ │ ├── IccBAcsProcessElement.cs │ │ ├── IccClutProcessElement.cs │ │ ├── IccCurveSetProcessElement.cs │ │ ├── IccEAcsProcessElement.cs │ │ ├── IccMatrixProcessElement.cs │ │ └── IccMultiProcessElement.cs │ │ ├── TagDataEntries │ │ ├── IccChromaticityTagDataEntry.cs │ │ ├── IccColorantOrderTagDataEntry.cs │ │ ├── IccColorantTableTagDataEntry.cs │ │ ├── IccCrdInfoTagDataEntry.cs │ │ ├── IccCurveTagDataEntry.cs │ │ ├── IccDataTagDataEntry.cs │ │ ├── IccDateTimeTagDataEntry.cs │ │ ├── IccFix16ArrayTagDataEntry.cs │ │ ├── IccLut16TagDataEntry.cs │ │ ├── IccLut8TagDataEntry.cs │ │ ├── IccLutAToBTagDataEntry.cs │ │ ├── IccLutBToATagDataEntry.cs │ │ ├── IccMeasurementTagDataEntry.cs │ │ ├── IccMultiLocalizedUnicodeTagDataEntry.cs │ │ ├── IccMultiProcessElementsTagDataEntry.cs │ │ ├── IccNamedColor2TagDataEntry.cs │ │ ├── IccParametricCurveTagDataEntry.cs │ │ ├── IccProfileSequenceDescTagDataEntry.cs │ │ ├── IccProfileSequenceIdentifierTagDataEntry.cs │ │ ├── IccResponseCurveSet16TagDataEntry.cs │ │ ├── IccScreeningTagDataEntry.cs │ │ ├── IccSignatureTagDataEntry.cs │ │ ├── IccTextDescriptionTagDataEntry.cs │ │ ├── IccTextTagDataEntry.cs │ │ ├── IccUFix16ArrayTagDataEntry.cs │ │ ├── IccUInt16ArrayTagDataEntry.cs │ │ ├── IccUInt32ArrayTagDataEntry.cs │ │ ├── IccUInt64ArrayTagDataEntry.cs │ │ ├── IccUInt8ArrayTagDataEntry.cs │ │ ├── IccUcrBgTagDataEntry.cs │ │ ├── IccUnknownTagDataEntry.cs │ │ ├── IccViewingConditionsTagDataEntry.cs │ │ └── IccXyzTagDataEntry.cs │ │ └── Various │ │ ├── IccClut.cs │ │ ├── IccColorantTableEntry.cs │ │ ├── IccLocalizedString.cs │ │ ├── IccLut.cs │ │ ├── IccNamedColor.cs │ │ ├── IccPositionNumber.cs │ │ ├── IccProfileDescription.cs │ │ ├── IccProfileId.cs │ │ ├── IccProfileSequenceIdentifier.cs │ │ ├── IccResponseNumber.cs │ │ ├── IccScreeningChannel.cs │ │ └── IccTagTableEntry.cs ├── PixelTypeInfo.cs ├── Png │ ├── Filters │ │ ├── AverageFilter.cs │ │ ├── FilterType.cs │ │ ├── NoneFilter.cs │ │ ├── PaethFilter.cs │ │ ├── SubFilter.cs │ │ └── UpFilter.cs │ ├── IPngDecoderOptions.cs │ ├── PngChunk.cs │ ├── PngChunkType.cs │ ├── PngColorType.cs │ ├── PngConfigurationModule.cs │ ├── PngConstants.cs │ ├── PngDecoder.cs │ ├── PngDecoderCore.cs │ ├── PngEncoder.cs │ ├── PngEncoderCore.cs │ ├── PngFilterMethod.cs │ ├── PngFormat.cs │ ├── PngHeader.cs │ ├── PngImageFormatDetector.cs │ ├── PngInterlaceMode.cs │ ├── README.md │ └── Zlib │ │ ├── Adler32.cs │ │ ├── Crc32.cs │ │ ├── IChecksum.cs │ │ ├── README.md │ │ ├── ZlibDeflateStream.cs │ │ └── ZlibInflateStream.cs ├── Quantization │ └── IQuantizer.cs ├── Utils │ ├── DebugGuard.cs │ ├── DenseMatrix.cs │ ├── Endianness.cs │ ├── Guard.cs │ ├── HashHelpers.cs │ ├── ImageMaths.cs │ ├── LongRational.cs │ ├── MathF.cs │ ├── Rational.cs │ ├── SignedRational.cs │ ├── SpanClassHelper.cs │ └── Vector4Pair.cs └── readme.md ├── Geb.Image.csproj ├── Geb.Image.csproj.user ├── IImage.cs ├── ManagedImage └── ComplexImage.cs ├── Properties └── PublishProfiles │ ├── FolderProfile.pubxml │ └── FolderProfile.pubxml.user ├── UnmanagedImage ├── FilterKernel.cs ├── Image.cs ├── ImageBgr24.cs ├── ImageBgra32.cs ├── ImageCieLab.cs ├── ImageCieXyz.cs ├── ImageCmyk.cs ├── ImageExtensions.cs ├── ImageFBgr96.cs ├── ImageFloat.cs ├── ImageGrad.cs ├── ImageGradXY.cs ├── ImageHsl.cs ├── ImageInt16.cs ├── ImageInt32.cs ├── ImageLAlphaBeta.cs ├── ImageLab24.cs ├── ImageRgbS.cs ├── ImageSBgra64.cs ├── ImageU8.cs ├── ImageU8 │ └── ImageU8_Sobel.cs ├── PixelFormats.cs ├── Templates │ ├── _ImageBgr24.cs │ ├── _ImageBgr24_Csmacro.cs │ ├── _ImageBgra32.cs │ ├── _ImageBgra32_Csmacro.cs │ ├── _ImageFBgr96.cs │ ├── _ImageFBgr96_Csmacro.cs │ ├── _ImageFloat.cs │ ├── _ImageFloat_Csmacro.cs │ ├── _ImageGrad.cs │ ├── _ImageGradXY.cs │ ├── _ImageGradXY_Csmacro.cs │ ├── _ImageGrad_Csmacro.cs │ ├── _ImageHsl.cs │ ├── _ImageHsl_Csmacro.cs │ ├── _ImageInt16.cs │ ├── _ImageInt16_Csmacro.cs │ ├── _ImageInt32.cs │ ├── _ImageInt32_Csmacro.cs │ ├── _ImageLab24.cs │ ├── _ImageLab24_Csmacro.cs │ ├── _ImageRgbS.cs │ ├── _ImageRgbS_Csmacro.cs │ ├── _ImageSBgra64.cs │ ├── _ImageSBgra64_Csmacro.cs │ ├── _ImageU8.cs │ ├── _ImageU8_Csmacro.cs │ ├── __ImageClassHelper_Template.cs │ ├── __ImageFilter_Template.cs │ ├── __Image_Template.cs │ ├── __Paramid_Templete.cs │ └── __Pixel_Template.cs └── Utils │ ├── HersheyGlyphs.cs │ ├── ImageConverter.cs │ ├── ImageReader.cs │ └── PixelHelper.cs └── Utils ├── AffineTransform.cs ├── Geometry.cs ├── ImageSamplingAlgorithm.cs ├── Interpolate.cs └── ProjectionTransform.cs /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /Geb.Common.suo 3 | Debug 4 | Release 5 | /bin 6 | obj 7 | old 8 | Publish 9 | *.suo 10 | /TestResults 11 | *.pfx 12 | *.userprefs 13 | libs/ 14 | src/bin/ 15 | .vs/ 16 | lib/ 17 | *.nupkg 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GebImage 2 | ======== 3 | 4 | Geb.Image 是一款为图像分析目的而构建的易用、高性能的 C# 图像库。图像、视频这样的数据占人类数据总量的绝大部分,自 2008 年转型图像和视频开发时起,我就在找寻一个开发语言,能够高效的处理图像和视频数据,同时又具有高开发速度。经过多方比对,最终选择了 C#。C# 是一个成熟的快速开发语言,而打开 unsafe 后,可以直接用指针操作内存数据,能够实现接近于 C 语言的性能。Geb.Image 是我的一个尝试。 5 | 6 | 本项目有以下特色: 7 | 8 | - 高性能:计算密集部分使用指针开发 9 | 10 | - 自包含:是纯的 .net 库,不包含第三方 native dll 11 | 12 | - 自2.0起,支持.Net 2.0 标准 13 | 14 | - 兼容 dotnet/CoreRT,方便编译为独立 exe 程序发布 15 | -------------------------------------------------------------------------------- /examples/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Script Debug", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "program": "dotnet", 9 | "args": [ 10 | "exec", 11 | "C:/Users/hufei/.dotnet/tools/.store/dotnet-script/0.53.0/dotnet-script/0.53.0/tools/netcoreapp3.1/any/dotnet-script.dll", 12 | "${file}" 13 | ], 14 | "cwd": "${workspaceRoot}", 15 | "stopAtEntry": true 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /examples/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaotie/GebImage/cd6fbf4e05a039bf392a6fd5961610cb81161b4e/examples/1.png -------------------------------------------------------------------------------- /examples/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaotie/GebImage/cd6fbf4e05a039bf392a6fd5961610cb81161b4e/examples/2.png -------------------------------------------------------------------------------- /examples/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaotie/GebImage/cd6fbf4e05a039bf392a6fd5961610cb81161b4e/examples/3.png -------------------------------------------------------------------------------- /examples/basic/basic.csx: -------------------------------------------------------------------------------- 1 | #load "../common.csx" 2 | 3 | using Geb.Image; 4 | 5 | ImageBgra32 img = new ImageBgra32(100,100); 6 | Console.WriteLine(img[32]); -------------------------------------------------------------------------------- /examples/basic/bitmap.csx: -------------------------------------------------------------------------------- 1 | #load "../common.csx" 2 | 3 | using Geb.Image; 4 | using System.Drawing; 5 | 6 | Bitmap bitmap = new Bitmap(100,100); 7 | ImageU8 img = new ImageU8(bitmap); 8 | Console.WriteLine(img[3,3]); 9 | for(int i = 0; i < img.Length; i++) 10 | img[i] = (Byte)(i % 255); 11 | bitmap = img.ToBitmap(); 12 | Console.WriteLine(bitmap.GetPixel(3,3)); 13 | img.ApplyGaussianBlur(); 14 | Console.WriteLine(img[3,3]); 15 | -------------------------------------------------------------------------------- /examples/basic/resize.csx: -------------------------------------------------------------------------------- 1 | #load "../common.csx" 2 | 3 | using Geb.Image; 4 | 5 | ImageBgr24 img = new ImageBgr24(80,100); 6 | for(int h = 0; h < img.Height; h++) 7 | { 8 | for(int w = 0; w < img.Width; w++) 9 | { 10 | int g = (h + w)*100; 11 | Bgr24 val = new Bgr24(g,g,g); 12 | img[h,w] = val; 13 | } 14 | } 15 | 16 | ImageBgr24 img2 = img.Resize(60,60,InterpolationMode.Bilinear); 17 | Console.WriteLine(img[1,1]); 18 | Console.WriteLine(img[1,2]); 19 | Console.WriteLine(img[2,1]); 20 | Console.WriteLine(img[2,2]); 21 | Console.WriteLine(img2[1,1]); 22 | 23 | ImageBgr24 img3 = img.Resize(120,180,InterpolationMode.Bilinear); 24 | 25 | double ax = 0.3333334; 26 | double ay = 0.666666; 27 | double bx = 1 -ax; 28 | double by = 1 - ay; 29 | 30 | double v = 200*bx*by + 44 * ax * by + 44 * bx*ay + 144 * ax * ay; 31 | Console.WriteLine(v); 32 | 33 | // img.Save("1.png"); 34 | // img2.Save("2.png"); 35 | // img3.Save("3.png"); 36 | 37 | -------------------------------------------------------------------------------- /examples/common.csx: -------------------------------------------------------------------------------- 1 | #r "nuget: System.Drawing.Common, 4.7.0" 2 | #r "../src/Geb.Image/bin/Debug/netstandard2.0/Geb.Image.dll" 3 | -------------------------------------------------------------------------------- /examples/omnisharp.json: -------------------------------------------------------------------------------- 1 | { 2 | "script": { 3 | "enableScriptNuGetReferences": true, 4 | "defaultTargetFramework": "netcoreapp2.1" 5 | } 6 | } -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /pack/gebimage.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Geb.Image 5 | 2.0.3 6 | Geb Image Library 7 | hufei(geblab) 8 | http://opensource.org/licenses/MS-PL 9 | https://github.com/xiaotie/GebImage 10 | http://www.geblab.com/Content/images/logo.png 11 | false 12 | Geb Image Library 13 | en-US 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /pack/nugetpack.bat: -------------------------------------------------------------------------------- 1 | nuget pack gebimage.nuspec 2 | -------------------------------------------------------------------------------- /src/Geb.Image.OpenCV/Geb.Image.OpenCV.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 5.0.2 6 | 7 | 8 | 9 | true 10 | 11 | 12 | 13 | true 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Geb.Image.OpenCV/MatClassHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using OpenCvSharp; 5 | 6 | namespace Geb.Image 7 | { 8 | public static class MatClassHelper 9 | { 10 | public unsafe static Mat ToCVMat(this ImageU8 img) 11 | { 12 | Mat mat = new Mat(img.Height, img.Width,MatType.CV_8U, img.StartIntPtr, img.Stride ); 13 | return mat; 14 | } 15 | 16 | public unsafe static Mat ToCVMat(this ImageBgr24 img) 17 | { 18 | Mat mat = new Mat(img.Height, img.Width, MatType.CV_8UC3, img.StartIntPtr, img.Stride); 19 | return mat; 20 | } 21 | 22 | public unsafe static ImageU8 ToImageU8(this Mat mat) 23 | { 24 | if (mat == null) return null; 25 | if (mat.ElemSize() != 1) throw new ArgumentException("Element size is not 1"); 26 | ImageU8 img = new ImageU8(mat.Width, mat.Height); 27 | long srcStride = mat.Step(); 28 | long dstStride = img.Stride; 29 | Byte* src0 = mat.DataPointer; 30 | Byte* dst0 = img.Start; 31 | 32 | if(srcStride == dstStride) 33 | { 34 | // 整体 copy 35 | int bytes = (int)(srcStride * img.Height); 36 | Span spanSrc = new Span(src0, bytes); 37 | Span spanDst = new Span(dst0, bytes); 38 | spanSrc.CopyTo(spanDst); 39 | } 40 | else 41 | { 42 | // 逐行 copy 43 | int lineBytes = img.Width; 44 | for (int r = 0; r < img.Height; r++) 45 | { 46 | Span spanSrc = new Span(src0, lineBytes); 47 | Span spanDst = new Span(dst0, lineBytes); 48 | spanSrc.CopyTo(spanDst); 49 | src0 += srcStride; 50 | dst0 += dstStride; 51 | } 52 | } 53 | return img; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Geb.Image.Test/Geb.Image.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | PreserveNewest 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Geb.Image.Test/ImageResizeTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System.IO; 3 | 4 | namespace Geb.Image.Test 5 | { 6 | [TestClass] 7 | public class ImageResizeTest 8 | { 9 | [TestMethod] 10 | public void TestDecode() 11 | { 12 | ImageBgr24 img = new ImageBgr24(80, 100); 13 | for (int h = 0; h < img.Height; h++) 14 | { 15 | for (int w = 0; w < img.Width; w++) 16 | { 17 | int g = (h + w) * 100; 18 | Bgr24 val = new Bgr24(g, g, g); 19 | img[h, w] = val; 20 | } 21 | } 22 | 23 | ImageBgr24 img2 = img.Resize(60, 60, InterpolationMode.Bilinear); 24 | Bgr24 c = img2[1, 1]; 25 | Assert.AreEqual(101, c.Blue); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Geb.Image.Test/img/demo-bmp-24.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaotie/GebImage/cd6fbf4e05a039bf392a6fd5961610cb81161b4e/src/Geb.Image.Test/img/demo-bmp-24.bmp -------------------------------------------------------------------------------- /src/Geb.Image.Test/img/demo-bmp-big-01.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaotie/GebImage/cd6fbf4e05a039bf392a6fd5961610cb81161b4e/src/Geb.Image.Test/img/demo-bmp-big-01.bmp -------------------------------------------------------------------------------- /src/Geb.Image.WinForm/BitmapHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Geb.Image 8 | { 9 | using Geb.Image.WinForm; 10 | 11 | public class GeneratorWarpper 12 | { 13 | private Func _func; 14 | public GeneratorWarpper(Func func) 15 | { 16 | _func = func; 17 | } 18 | 19 | public Bitmap Generate() 20 | { 21 | var img = _func.Invoke(); 22 | return img == null ? null : img.ToBitmap(); 23 | } 24 | } 25 | 26 | public static class BitmapHelper 27 | { 28 | public static System.Windows.Forms.DialogResult ShowDialog(this Bitmap bmp, String title = null) 29 | { 30 | if (bmp == null) return System.Windows.Forms.DialogResult.Cancel; 31 | 32 | FrmImage frm = new FrmImage(); 33 | frm.Bitmap = bmp; 34 | if (title != null) { frm.Text = title; } 35 | return frm.ShowDialog(); 36 | } 37 | 38 | public static System.Windows.Forms.DialogResult ShowDialog(this IImage image, String title = null) 39 | { 40 | if (image == null) return System.Windows.Forms.DialogResult.Cancel; 41 | return image.ToBitmap().ShowDialog(title); 42 | } 43 | 44 | public static System.Windows.Forms.DialogResult ShowDialog(this Func generator, String title = null) 45 | { 46 | return ShowDialog(new GeneratorWarpper(generator).Generate, title); 47 | } 48 | 49 | public static System.Windows.Forms.DialogResult ShowDialog(this Func generator, String title = null) 50 | { 51 | if (generator == null) return System.Windows.Forms.DialogResult.Cancel; 52 | 53 | FrmImage frm = new FrmImage(); 54 | frm.Generator = generator; 55 | if (title != null) { frm.Text = title; } 56 | return frm.ShowDialog(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Geb.Image.WinForm/FrmImage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace Geb.Image.WinForm 12 | { 13 | public partial class FrmImage : Form 14 | { 15 | public Bitmap Bitmap { get; set; } 16 | 17 | public Func Generator { get; set; } 18 | 19 | public FrmImage() 20 | { 21 | InitializeComponent(); 22 | } 23 | 24 | private void FrmImage_Load(object sender, EventArgs e) 25 | { 26 | if (Bitmap != null) 27 | { 28 | this.imageBox.Image = Bitmap; 29 | } 30 | 31 | if(Generator != null) 32 | { 33 | this.backgroundWorker.RunWorkerAsync(); 34 | } 35 | } 36 | 37 | delegate void InvokeUpdate(); 38 | 39 | private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 40 | { 41 | while(true) 42 | { 43 | var bmp = Generator.Invoke(); 44 | if (bmp == null) break; 45 | this.Invoke(new InvokeUpdate(()=> { this.ShowBitmap(bmp); })); 46 | } 47 | } 48 | 49 | private void ShowBitmap(Bitmap bmp) 50 | { 51 | Bitmap oldBitmap = this.imageBox.Image as Bitmap; 52 | this.imageBox.Image = bmp; 53 | if (oldBitmap != null) oldBitmap.Dispose(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Geb.Image.WinForm/Geb.Image.WinForm.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net5.0-windows 5 | true 6 | 5.0.0 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Geb.Image.WinForm/Geb.Image.WinForm.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Form 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Geb.Image/Common/Config.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image 6 | { 7 | public static class Config 8 | { 9 | /// 10 | /// 安静模式。安静模式下Geb.Image程序库不会弹出窗体。 11 | /// 默认为 false。 12 | /// 13 | public static Boolean SilentMode = false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Geb.Image/Common/Enums.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2012 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Geb.Image 10 | { 11 | /// 12 | /// Dispose 策略 13 | /// 14 | public enum DisposePolicy 15 | { 16 | /// 17 | /// 不进行Dispose 18 | /// 19 | None = 0, 20 | 21 | /// 22 | /// Dispose调用方 23 | /// 24 | DisposeCaller = 1 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Geb.Image/Common/ImagePool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image 6 | { 7 | public class ImagePool 8 | { 9 | public int Deep; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Geb.Image/Common/MemoryStorage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Collections.Generic; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace Geb.Image 8 | { 9 | public unsafe class MemoryStorage : IDisposable 10 | { 11 | public int _bytes; 12 | public int Bytes 13 | { 14 | get { return _bytes; } 15 | } 16 | 17 | private byte* _start; 18 | 19 | public Byte* Start 20 | { 21 | get { return _start; } 22 | } 23 | 24 | public MemoryStorage(int bytes) 25 | { 26 | if (bytes < 0) throw new ArgumentOutOfRangeException("bytes 不能为负"); 27 | _bytes = bytes; 28 | IntPtr ptr = Marshal.AllocHGlobal(bytes); 29 | _start = (Byte*)ptr; 30 | } 31 | 32 | public void Resize(int newSize) 33 | { 34 | if (newSize < 0) throw new ArgumentOutOfRangeException("newSize 不能为负"); 35 | byte* newStart = (Byte*)Marshal.AllocHGlobal(newSize); 36 | if(_start != null) 37 | { 38 | int size = Math.Min(_bytes, newSize); 39 | Unsafe.CopyBlockUnaligned(newStart, _start, (uint)size); 40 | Marshal.FreeHGlobal((IntPtr)_start); 41 | } 42 | _start = newStart; 43 | } 44 | 45 | public void Dispose() 46 | { 47 | if(_start != null) 48 | { 49 | IntPtr ptr = (IntPtr)_start; 50 | _start = null; 51 | Marshal.FreeHGlobal(ptr); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Geb.Image/Common/PixelFormat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image 6 | { 7 | public enum PixelFormat 8 | { 9 | Format32bppBgra, Format24bppBgr, Format8bpp, Format72bppRgbS 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Geb.Image/Common/Range.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Geb.Image 10 | { 11 | public class Range : IComparable 12 | { 13 | public int Min { get; set; } 14 | public int Max { get; set; } 15 | 16 | public Range() 17 | { } 18 | 19 | public Range(int min, int max) 20 | { 21 | this.Min = min; 22 | this.Max = max; 23 | } 24 | 25 | public int Width { get { return Max - Min + 1; } } 26 | 27 | public Int32 Distance 28 | { 29 | get { return Max - Min; } 30 | } 31 | 32 | #region IComparable Members 33 | 34 | public int CompareTo(Range other) 35 | { 36 | return this.Distance.CompareTo(other.Distance); 37 | } 38 | 39 | #endregion 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpBitsPerPixel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Bmp 6 | { 7 | /// 8 | /// Enumerates the available bits per pixel for bitmap. 9 | /// 10 | public enum BmpBitsPerPixel 11 | { 12 | /// 13 | /// 24 bits per pixel. Each pixel consists of 3 bytes. 14 | /// 15 | Pixel24 = 3, 16 | 17 | /// 18 | /// 32 bits per pixel. Each pixel consists of 4 bytes. 19 | /// 20 | Pixel32 = 4 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Bmp 6 | { 7 | /// 8 | /// Defines constants relating to BMPs 9 | /// 10 | internal static class BmpConstants 11 | { 12 | /// 13 | /// The list of mimetypes that equate to a bmp. 14 | /// 15 | public static readonly IEnumerable MimeTypes = new[] { "image/bmp", "image/x-windows-bmp" }; 16 | 17 | /// 18 | /// The list of file extensions that equate to a bmp. 19 | /// 20 | public static readonly IEnumerable FileExtensions = new[] { "bm", "bmp", "dip" }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats.Bmp 7 | { 8 | /// 9 | /// Image decoder for generating an image out of a Windows bitmap stream. 10 | /// 11 | /// 12 | /// Does not support the following formats at the moment: 13 | /// 14 | /// JPG 15 | /// PNG 16 | /// RLE4 17 | /// RLE8 18 | /// BitFields 19 | /// 20 | /// Formats will be supported in a later releases. We advise always 21 | /// to use only 24 Bit Windows bitmaps. 22 | /// 23 | public sealed class BmpDecoder : IImageDecoder 24 | { 25 | /// 26 | public ImageBgra32 Decode(Stream stream) 27 | { 28 | return new BmpDecoderCore().Decode(stream); 29 | } 30 | 31 | public ImageBgra32 Decode(String path) 32 | { 33 | using (FileStream fs = new FileStream(path, FileMode.Open)) 34 | { 35 | return new BmpDecoderCore().Decode(fs); 36 | } 37 | } 38 | 39 | /// 40 | public IImageInfo Identify(Stream stream) 41 | { 42 | return new BmpDecoderCore().Identify(stream); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpEncoder.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Geb.Image.Formats.Bmp 4 | { 5 | /// 6 | /// Image encoder for writing an image to a stream as a Windows bitmap. 7 | /// 8 | /// The encoder can currently only write 24-bit rgb images to streams. 9 | public sealed class BmpEncoder 10 | { 11 | /// 12 | /// Gets or sets the number of bits per pixel. 13 | /// 14 | public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24; 15 | 16 | /// 17 | public void Encode(ImageBgra32 image, Stream stream) 18 | { 19 | var encoder = new BmpEncoderCore(BmpBitsPerPixel.Pixel32); 20 | encoder.Encode(image, stream); 21 | } 22 | 23 | public void Encode(ImageBgra32 image, string path) 24 | { 25 | using (FileStream fs = new FileStream(path, FileMode.CreateNew)) 26 | { 27 | Encode(image, fs); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpFileHeader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace Geb.Image.Formats.Bmp 6 | { 7 | /// 8 | /// Stores general information about the Bitmap file. 9 | /// 10 | /// 11 | /// 12 | /// The first two bytes of the Bitmap file format 13 | /// (thus the Bitmap header) are stored in big-endian order. 14 | /// All of the other integer values are stored in little-endian format 15 | /// (i.e. least-significant byte first). 16 | /// 17 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 18 | internal readonly struct BmpFileHeader 19 | { 20 | /// 21 | /// Defines of the data structure in the bitmap file. 22 | /// 23 | public const int Size = 14; 24 | 25 | public BmpFileHeader(short type, int fileSize, int reserved, int offset) 26 | { 27 | this.Type = type; 28 | this.FileSize = fileSize; 29 | this.Reserved = reserved; 30 | this.Offset = offset; 31 | } 32 | 33 | /// 34 | /// Gets the Bitmap identifier. 35 | /// The field used to identify the bitmap file: 0x42 0x4D 36 | /// (Hex code points for B and M) 37 | /// 38 | public short Type { get; } 39 | 40 | /// 41 | /// Gets the size of the bitmap file in bytes. 42 | /// 43 | public int FileSize { get; } 44 | 45 | /// 46 | /// Gets any reserved data; actual value depends on the application 47 | /// that creates the image. 48 | /// 49 | public int Reserved { get; } 50 | 51 | /// 52 | /// Gets the offset, i.e. starting address, of the byte where 53 | /// the bitmap data can be found. 54 | /// 55 | public int Offset { get; } 56 | 57 | public static BmpFileHeader Parse(Span data) 58 | { 59 | return MemoryMarshal.Cast(data)[0]; 60 | } 61 | 62 | public unsafe void WriteTo(Span buffer) 63 | { 64 | ref BmpFileHeader dest = ref Unsafe.As(ref MemoryMarshal.GetReference(buffer)); 65 | 66 | dest = this; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpFormat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Bmp 6 | { 7 | /// 8 | /// Registers the image encoders, decoders and mime type detectors for the bmp format. 9 | /// 10 | internal sealed class BmpFormat : IImageFormat 11 | { 12 | /// 13 | public string Name => "BMP"; 14 | 15 | /// 16 | public string DefaultMimeType => "image/bmp"; 17 | 18 | /// 19 | public IEnumerable MimeTypes => BmpConstants.MimeTypes; 20 | 21 | /// 22 | public IEnumerable FileExtensions => BmpConstants.FileExtensions; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Bmp/BmpImageFormatDetector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Bmp 6 | { 7 | /// 8 | /// Detects bmp file headers 9 | /// 10 | public sealed class BmpImageFormatDetector : IImageFormatDetector 11 | { 12 | /// 13 | public int HeaderSize => 2; 14 | 15 | /// 16 | public IImageFormat DetectFormat(ReadOnlySpan header) 17 | { 18 | if (this.IsSupportedFileFormat(header)) 19 | { 20 | return ImageFormats.Bmp; 21 | } 22 | 23 | return null; 24 | } 25 | 26 | private bool IsSupportedFileFormat(ReadOnlySpan header) 27 | { 28 | // TODO: This should be in constants 29 | return header.Length >= this.HeaderSize && 30 | header[0] == 0x42 && // B 31 | header[1] == 0x4D; // M 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Extentions/AdvancedImageExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Extentions 6 | { 7 | class AdvancedImageExtensions 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Extentions/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats 7 | { 8 | /// 9 | /// Extension methods for the type. 10 | /// 11 | internal static class StreamExtensions 12 | { 13 | /// 14 | /// Skips the number of bytes in the given stream. 15 | /// 16 | /// The stream. 17 | /// The count. 18 | public static void Skip(this Stream stream, int count) 19 | { 20 | if (count < 1) 21 | { 22 | return; 23 | } 24 | 25 | if (stream.CanSeek) 26 | { 27 | stream.Seek(count, SeekOrigin.Current); // Position += count; 28 | } 29 | else 30 | { 31 | byte[] foo = new byte[count]; 32 | while (count > 0) 33 | { 34 | int bytesRead = stream.Read(foo, 0, count); 35 | if (bytesRead == 0) 36 | { 37 | break; 38 | } 39 | 40 | count -= bytesRead; 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/DisposalMethod.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Gif 5 | { 6 | /// 7 | /// Provides enumeration for instructing the decoder what to do with the last image 8 | /// in an animation sequence. 9 | /// section 23 10 | /// 11 | public enum DisposalMethod 12 | { 13 | /// 14 | /// No disposal specified. 15 | /// The decoder is not required to take any action. 16 | /// 17 | Unspecified = 0, 18 | 19 | /// 20 | /// Do not dispose. 21 | /// The graphic is to be left in place. 22 | /// 23 | NotDispose = 1, 24 | 25 | /// 26 | /// Restore to background color. 27 | /// The area used by the graphic must be restored to the background color. 28 | /// 29 | RestoreToBackground = 2, 30 | 31 | /// 32 | /// Restore to previous. 33 | /// The decoder is required to restore the area overwritten by the 34 | /// graphic with what was there prior to rendering the graphic. 35 | /// 36 | RestoreToPrevious = 3 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/FrameDecodingMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Gif 5 | { 6 | /// 7 | /// Enumerated frame process modes to apply to multi-frame images. 8 | /// 9 | public enum FrameDecodingMode 10 | { 11 | /// 12 | /// Decodes all the frames of a multi-frame image. 13 | /// 14 | All, 15 | 16 | /// 17 | /// Decodes only the first frame of a multi-frame image. 18 | /// 19 | First 20 | } 21 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/GifConfigurationModule.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Gif 5 | { 6 | /// 7 | /// Registers the image encoders, decoders and mime type detectors for the gif format. 8 | /// 9 | public sealed class GifConfigurationModule : IConfigurationModule 10 | { 11 | /// 12 | public void Configure(Configuration config) 13 | { 14 | //config.ImageFormatsManager.SetEncoder(ImageFormats.Gif, new GifEncoder()); 15 | //config.ImageFormatsManager.SetDecoder(ImageFormats.Gif, new GifDecoder()); 16 | 17 | //config.ImageFormatsManager.AddImageFormatDetector(new GifImageFormatDetector()); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/GifDecoder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | using System; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace Geb.Image.Formats.Gif 8 | { 9 | /// 10 | /// Decoder for generating an image out of a gif encoded stream. 11 | /// 12 | public sealed class GifDecoder : IGifDecoderOptions 13 | { 14 | /// 15 | /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. 16 | /// 17 | public bool IgnoreMetadata { get; set; } = false; 18 | 19 | /// 20 | /// Gets or sets the encoding that should be used when reading comments. 21 | /// 22 | public Encoding TextEncoding { get; set; } = GifConstants.DefaultEncoding; 23 | 24 | /// 25 | /// Gets or sets the decoding mode for multi-frame images 26 | /// 27 | public FrameDecodingMode DecodingMode { get; set; } = FrameDecodingMode.All; 28 | 29 | /// 30 | public ImageBgra32 Decode(Configuration configuration, Stream stream) 31 | { 32 | //var decoder = new GifDecoderCore(configuration, this); 33 | //return decoder.Decode(stream); 34 | throw new NotImplementedException(); 35 | } 36 | 37 | /// 38 | public IImageInfo Identify(Configuration configuration, Stream stream) 39 | { 40 | Guard.NotNull(stream, "stream"); 41 | 42 | var decoder = new GifDecoderCore(configuration, this); 43 | return decoder.Identify(stream); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/GifEncoder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.IO; 5 | using System.Text; 6 | using Geb.Image.Formats.Quantization; 7 | 8 | namespace Geb.Image.Formats.Gif 9 | { 10 | /// 11 | /// Image encoder for writing image data to a stream in gif format. 12 | /// 13 | public sealed class GifEncoder : IGifEncoderOptions 14 | { 15 | /// 16 | /// Gets or sets a value indicating whether the metadata should be ignored when the image is being encoded. 17 | /// 18 | public bool IgnoreMetadata { get; set; } = false; 19 | 20 | /// 21 | /// Gets or sets the encoding that should be used when writing comments. 22 | /// 23 | public Encoding TextEncoding { get; set; } = GifConstants.DefaultEncoding; 24 | 25 | /// 26 | /// Gets or sets the quantizer for reducing the color count. 27 | /// Defaults to the 28 | /// 29 | public IQuantizer Quantizer { get; set; } /*= new OctreeQuantizer();*/ 30 | 31 | /// 32 | public void Encode(ImageBgra32 image, Stream stream) 33 | { 34 | //var encoder = new GifEncoderCore(image.GetConfiguration().MemoryManager, this); 35 | //encoder.Encode(image, stream); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/GifFormat.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Geb.Image.Formats.Gif 7 | { 8 | /// 9 | /// Registers the image encoders, decoders and mime type detectors for the gif format. 10 | /// 11 | internal sealed class GifFormat : IImageFormat 12 | { 13 | /// 14 | public string Name => "GIF"; 15 | 16 | /// 17 | public string DefaultMimeType => "image/gif"; 18 | 19 | /// 20 | public IEnumerable MimeTypes => GifConstants.MimeTypes; 21 | 22 | /// 23 | public IEnumerable FileExtensions => GifConstants.FileExtensions; 24 | } 25 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/GifImageFormatDetector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.Gif 7 | { 8 | /// 9 | /// Detects gif file headers 10 | /// 11 | public sealed class GifImageFormatDetector : IImageFormatDetector 12 | { 13 | /// 14 | public int HeaderSize => 6; 15 | 16 | /// 17 | public IImageFormat DetectFormat(ReadOnlySpan header) 18 | { 19 | return this.IsSupportedFileFormat(header) ? ImageFormats.Gif : null; 20 | } 21 | 22 | private bool IsSupportedFileFormat(ReadOnlySpan header) 23 | { 24 | return header.Length >= this.HeaderSize && 25 | header[0] == 0x47 && // G 26 | header[1] == 0x49 && // I 27 | header[2] == 0x46 && // F 28 | header[3] == 0x38 && // 8 29 | (header[4] == 0x39 || header[4] == 0x37) && // 9 or 7 30 | header[5] == 0x61; // a 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/IGifDecoderOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats.Gif 7 | { 8 | /// 9 | /// Decoder for generating an image out of a gif encoded stream. 10 | /// 11 | internal interface IGifDecoderOptions 12 | { 13 | /// 14 | /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. 15 | /// 16 | bool IgnoreMetadata { get; } 17 | 18 | /// 19 | /// Gets the text encoding that should be used when reading comments. 20 | /// 21 | Encoding TextEncoding { get; } 22 | 23 | /// 24 | /// Gets the decoding mode for multi-frame images 25 | /// 26 | FrameDecodingMode DecodingMode { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/IGifEncoderOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Text; 5 | using Geb.Image.Formats.Quantization; 6 | 7 | namespace Geb.Image.Formats.Gif 8 | { 9 | /// 10 | /// The configuration options used for encoding gifs. 11 | /// 12 | internal interface IGifEncoderOptions 13 | { 14 | /// 15 | /// Gets a value indicating whether the metadata should be ignored when the image is being encoded. 16 | /// 17 | bool IgnoreMetadata { get; } 18 | 19 | /// 20 | /// Gets the text encoding used to write comments. 21 | /// 22 | Encoding TextEncoding { get; } 23 | 24 | /// 25 | /// Gets the quantizer used to generate the color palette. 26 | /// 27 | IQuantizer Quantizer { get; } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/README.md: -------------------------------------------------------------------------------- 1 | Encoder/Decoder adapted and extended from: 2 | 3 | https://github.com/yufeih/Nine.Imaging/ 4 | https://imagetools.codeplex.com/ 5 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Gif/Sections/IGifExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Geb.Image.Formats.Gif 4 | { 5 | /// 6 | /// A base interface for GIF extensions. 7 | /// 8 | public interface IGifExtension 9 | { 10 | /// 11 | /// Gets the label identifying the extensions. 12 | /// 13 | byte Label { get; } 14 | 15 | /// 16 | /// Writes the extension data to the buffer. 17 | /// 18 | /// The buffer to write the extension to. 19 | /// The number of bytes written to the buffer. 20 | int WriteTo(Span buffer); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/IConfigurationModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Represents an interface that can register image encoders, decoders and image format detectors. 9 | /// 10 | public interface IConfigurationModule 11 | { 12 | /// 13 | /// Called when loaded into a configuration object so the module can register items into the configuration. 14 | /// 15 | /// The configuration that will retain the encoders, decodes and mime type detectors. 16 | void Configure(Configuration configuration); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/IImageDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats 7 | { 8 | /// 9 | /// Encapsulates properties and methods required for decoding an image from a stream. 10 | /// 11 | public unsafe interface IImageDecoder 12 | { 13 | /// 14 | /// Decodes the image from the specified stream to the . 15 | /// 16 | /// The pixel format. 17 | /// The configuration for the image. 18 | /// The containing image data. 19 | /// The decoded image 20 | ImageBgra32 Decode(Stream stream); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/IImageFormat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Describes an image format. 9 | /// 10 | public interface IImageFormat 11 | { 12 | /// 13 | /// Gets the name that describes this image format. 14 | /// 15 | string Name { get; } 16 | 17 | /// 18 | /// Gets the default mimetype that the image foramt uses 19 | /// 20 | string DefaultMimeType { get; } 21 | 22 | /// 23 | /// Gets all the mimetypes that have been used by this image foramt. 24 | /// 25 | IEnumerable MimeTypes { get; } 26 | 27 | /// 28 | /// Gets the file extensions this image format commonly uses. 29 | /// 30 | IEnumerable FileExtensions { get; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/IImageFormatDetector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Used for detecting mime types from a file header 9 | /// 10 | public interface IImageFormatDetector 11 | { 12 | /// 13 | /// Gets the size of the header for this image type. 14 | /// 15 | /// The size of the header. 16 | int HeaderSize { get; } 17 | 18 | /// 19 | /// Detect mimetype 20 | /// 21 | /// The containing the file header. 22 | /// returns the mime type of detected othersie returns null 23 | IImageFormat DetectFormat(ReadOnlySpan header); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/IImageInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Encapsulates properties that descibe basic image information including dimensions, pixel type information 9 | /// and additional metadata 10 | /// 11 | public interface IImageInfo 12 | { 13 | /// 14 | /// Gets information about the image pixels. 15 | /// 16 | PixelTypeInfo PixelType { get; } 17 | 18 | /// 19 | /// Gets the width. 20 | /// 21 | int Width { get; } 22 | 23 | /// 24 | /// Gets the height. 25 | /// 26 | int Height { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/ImageFormatException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// The exception that is thrown when the library tries to load 9 | /// an image, which has an invalid format. 10 | /// 11 | public sealed class ImageFormatException : Exception 12 | { 13 | /// 14 | /// Initializes a new instance of the class with the name of the 15 | /// parameter that causes this exception. 16 | /// 17 | /// The error message that explains the reason for this exception. 18 | public ImageFormatException(string errorMessage) 19 | : base(errorMessage) 20 | { 21 | } 22 | 23 | /// 24 | /// Initializes a new instance of the class with a specified 25 | /// error message and the exception that is the cause of this exception. 26 | /// 27 | /// The error message that explains the reason for this exception. 28 | /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) 29 | /// if no inner exception is specified. 30 | public ImageFormatException(string errorMessage, Exception innerException) 31 | : base(errorMessage, innerException) 32 | { 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/ImageFormats.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// The static collection of all the default image formats 9 | /// 10 | public static class ImageFormats 11 | { 12 | /// 13 | /// The format details for the jpegs. 14 | /// 15 | public static readonly IImageFormat Jpeg = new Jpeg.JpegFormat(); 16 | 17 | /// 18 | /// The format details for the pngs. 19 | /// 20 | public static readonly IImageFormat Png = new Png.PngFormat(); 21 | 22 | /// 23 | /// The format details for the gifs. 24 | /// 25 | public static readonly IImageFormat Gif = new Gif.GifFormat(); 26 | 27 | /// 28 | /// The format details for the bitmaps. 29 | /// 30 | public static readonly IImageFormat Bmp = new Bmp.BmpFormat(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/ImageInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | using Geb.Image.Formats.MetaData; 6 | 7 | namespace Geb.Image.Formats 8 | { 9 | /// 10 | /// Contains information about the image including dimensions, pixel type information and additional metadata 11 | /// 12 | internal sealed class ImageInfo : IImageInfo 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// The image pixel type information. 18 | /// The width of the image in pixels. 19 | /// The height of the image in pixels. 20 | /// The images metadata. 21 | public ImageInfo(PixelTypeInfo pixelType, int width, int height, ImageMetaData meta = null) 22 | { 23 | this.PixelType = pixelType; 24 | this.Width = width; 25 | this.Height = height; 26 | this.MetaData = meta; 27 | } 28 | 29 | /// 30 | public PixelTypeInfo PixelType { get; } 31 | 32 | /// 33 | public int Width { get; } 34 | 35 | /// 36 | public int Height { get; } 37 | 38 | public ImageMetaData MetaData { get; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Numerics; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder.ColorConverters 8 | { 9 | internal abstract partial class JpegColorConverter 10 | { 11 | internal class FromCmyk : JpegColorConverter 12 | { 13 | public FromCmyk() 14 | : base(JpegColorSpace.Cmyk) 15 | { 16 | } 17 | 18 | public override void ConvertToRgba(ComponentValues values, Span result) 19 | { 20 | // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! 21 | ReadOnlySpan cVals = values.Component0; 22 | ReadOnlySpan mVals = values.Component1; 23 | ReadOnlySpan yVals = values.Component2; 24 | ReadOnlySpan kVals = values.Component3; 25 | 26 | var v = new Vector4(0, 0, 0, 1F); 27 | 28 | var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); 29 | 30 | for (int i = 0; i < result.Length; i++) 31 | { 32 | float c = cVals[i]; 33 | float m = mVals[i]; 34 | float y = yVals[i]; 35 | float k = kVals[i] / 255F; 36 | 37 | v.X = c * k; 38 | v.Y = m * k; 39 | v.Z = y * k; 40 | v.W = 1F; 41 | 42 | v *= scale; 43 | 44 | result[i] = v; 45 | } 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Numerics; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder.ColorConverters 8 | { 9 | internal abstract partial class JpegColorConverter 10 | { 11 | internal class FromGrayscale : JpegColorConverter 12 | { 13 | public FromGrayscale() 14 | : base(JpegColorSpace.Grayscale) 15 | { 16 | } 17 | 18 | public override void ConvertToRgba(ComponentValues values, Span result) 19 | { 20 | // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! 21 | ReadOnlySpan yVals = values.Component0; 22 | 23 | var v = new Vector4(0, 0, 0, 1); 24 | 25 | var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); 26 | 27 | for (int i = 0; i < result.Length; i++) 28 | { 29 | float y = yVals[i]; 30 | 31 | v.X = y; 32 | v.Y = y; 33 | v.Z = y; 34 | 35 | v *= scale; 36 | 37 | result[i] = v; 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Numerics; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder.ColorConverters 8 | { 9 | internal abstract partial class JpegColorConverter 10 | { 11 | internal class FromRgb : JpegColorConverter 12 | { 13 | public FromRgb() 14 | : base(JpegColorSpace.RGB) 15 | { 16 | } 17 | 18 | public override void ConvertToRgba(ComponentValues values, Span result) 19 | { 20 | // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! 21 | ReadOnlySpan rVals = values.Component0; 22 | ReadOnlySpan gVals = values.Component1; 23 | ReadOnlySpan bVals = values.Component2; 24 | 25 | var v = new Vector4(0, 0, 0, 1); 26 | 27 | var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); 28 | 29 | for (int i = 0; i < result.Length; i++) 30 | { 31 | float r = rVals[i]; 32 | float g = gVals[i]; 33 | float b = bVals[i]; 34 | 35 | v.X = r; 36 | v.Y = g; 37 | v.Z = b; 38 | 39 | v *= scale; 40 | 41 | result[i] = v; 42 | } 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Numerics; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder.ColorConverters 8 | { 9 | internal abstract partial class JpegColorConverter 10 | { 11 | internal class FromYCbCrBasic : JpegColorConverter 12 | { 13 | public FromYCbCrBasic() 14 | : base(JpegColorSpace.YCbCr) 15 | { 16 | } 17 | 18 | public override void ConvertToRgba(ComponentValues values, Span result) 19 | { 20 | ConvertCore(values, result); 21 | } 22 | 23 | internal static void ConvertCore(ComponentValues values, Span result) 24 | { 25 | // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! 26 | ReadOnlySpan yVals = values.Component0; 27 | ReadOnlySpan cbVals = values.Component1; 28 | ReadOnlySpan crVals = values.Component2; 29 | 30 | var v = new Vector4(0, 0, 0, 1); 31 | 32 | var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); 33 | 34 | for (int i = 0; i < result.Length; i++) 35 | { 36 | float y = yVals[i]; 37 | float cb = cbVals[i] - 128F; 38 | float cr = crVals[i] - 128F; 39 | 40 | v.X = MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero); 41 | v.Y = MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero); 42 | v.Z = MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero); 43 | 44 | v *= scale; 45 | 46 | result[i] = v; 47 | } 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Numerics; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder.ColorConverters 8 | { 9 | internal abstract partial class JpegColorConverter 10 | { 11 | internal class FromYccK : JpegColorConverter 12 | { 13 | public FromYccK() 14 | : base(JpegColorSpace.Ycck) 15 | { 16 | } 17 | 18 | public override void ConvertToRgba(ComponentValues values, Span result) 19 | { 20 | // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! 21 | ReadOnlySpan yVals = values.Component0; 22 | ReadOnlySpan cbVals = values.Component1; 23 | ReadOnlySpan crVals = values.Component2; 24 | ReadOnlySpan kVals = values.Component3; 25 | 26 | var v = new Vector4(0, 0, 0, 1F); 27 | 28 | var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); 29 | 30 | for (int i = 0; i < result.Length; i++) 31 | { 32 | float y = yVals[i]; 33 | float cb = cbVals[i] - 128F; 34 | float cr = crVals[i] - 128F; 35 | float k = kVals[i] / 255F; 36 | 37 | v.X = (255F - MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero)) * k; 38 | v.Y = (255F - MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero)) * k; 39 | v.Z = (255F - MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero)) * k; 40 | v.W = 1F; 41 | 42 | v *= scale; 43 | 44 | result[i] = v; 45 | } 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/IJpegComponent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Jpeg.Components.Decoder 5 | { 6 | /// 7 | /// Common interface to represent raw Jpeg components. 8 | /// 9 | internal interface IJpegComponent 10 | { 11 | /// 12 | /// Gets the component's position in the components array. 13 | /// 14 | int Index { get; } 15 | 16 | /// 17 | /// Gets the number of blocks in this component as 18 | /// 19 | Size SizeInBlocks { get; } 20 | 21 | /// 22 | /// Gets the horizontal and the vertical sampling factor as 23 | /// 24 | Size SamplingFactors { get; } 25 | 26 | /// 27 | /// Gets the divisors needed to apply when calculating colors. 28 | /// 29 | /// https://en.wikipedia.org/wiki/Chroma_subsampling 30 | /// 31 | /// In case of 4:2:0 subsampling the values are: Luma.SubSamplingDivisors = (1,1) Chroma.SubSamplingDivisors = (2,2) 32 | /// 33 | Size SubSamplingDivisors { get; } 34 | 35 | /// 36 | /// Gets the index of the quantization table for this block. 37 | /// 38 | int QuantizationTableIndex { get; } 39 | 40 | /// 41 | /// Gets the storing the "raw" frequency-domain decoded + unzigged blocks. 42 | /// We need to apply IDCT and dequantiazition to transform them into color-space blocks. 43 | /// 44 | Buffer2D SpectralBlocks { get; } 45 | 46 | /// 47 | /// Gets a reference to the at the given row and column index from 48 | /// 49 | /// The column 50 | /// The row 51 | /// The 52 | ref Block8x8 GetBlockReference(int column, int row); 53 | } 54 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/IRawJpegData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder 8 | { 9 | /// 10 | /// 11 | /// Represents decompressed, unprocessed jpeg data with spectral space -s. 12 | /// 13 | internal interface IRawJpegData : IDisposable 14 | { 15 | /// 16 | /// Gets the image size in pixels. 17 | /// 18 | Size ImageSizeInPixels { get; } 19 | 20 | /// 21 | /// Gets the number of coponents. 22 | /// 23 | int ComponentCount { get; } 24 | 25 | /// 26 | /// Gets the color space 27 | /// 28 | JpegColorSpace ColorSpace { get; } 29 | 30 | /// 31 | /// Gets the components. 32 | /// 33 | IEnumerable Components { get; } 34 | 35 | /// 36 | /// Gets the quantization tables, in zigzag order. 37 | /// 38 | Block8x8F[] QuantizationTables { get; } 39 | } 40 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/JpegColorSpace.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Jpeg.Components.Decoder 5 | { 6 | /// 7 | /// Identifies the colorspace of a Jpeg image 8 | /// 9 | internal enum JpegColorSpace 10 | { 11 | Undefined = 0, 12 | 13 | Grayscale, 14 | 15 | Ycck, 16 | 17 | Cmyk, 18 | 19 | RGB, 20 | 21 | YCbCr 22 | } 23 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Decoder/ProfileResolver.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Text; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components.Decoder 8 | { 9 | /// 10 | /// Provides methods for identifying metadata and color profiles within jpeg images. 11 | /// 12 | internal static class ProfileResolver 13 | { 14 | /// 15 | /// Describes the EXIF specific markers 16 | /// 17 | public static readonly byte[] JFifMarker = Encoding.UTF8.GetBytes("JFIF\0"); 18 | 19 | /// 20 | /// Describes the EXIF specific markers 21 | /// 22 | public static readonly byte[] IccMarker = Encoding.UTF8.GetBytes("ICC_PROFILE\0"); 23 | 24 | /// 25 | /// Describes the ICC specific markers 26 | /// 27 | public static readonly byte[] ExifMarker = Encoding.UTF8.GetBytes("Exif\0\0"); 28 | 29 | /// 30 | /// Describes Adobe specific markers 31 | /// 32 | public static readonly byte[] AdobeMarker = Encoding.UTF8.GetBytes("Adobe"); 33 | 34 | /// 35 | /// Returns a value indicating whether the passed bytes are a match to the profile identifer 36 | /// 37 | /// The bytes to check 38 | /// The profile identifier 39 | /// The 40 | public static bool IsProfile(Span bytesToCheck, Span profileIdentifier) 41 | { 42 | return bytesToCheck.Length >= profileIdentifier.Length 43 | && bytesToCheck.Slice(0, profileIdentifier.Length).SequenceEqual(profileIdentifier); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Encoder/BlockQuad.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Jpeg.Components.Encoder 5 | { 6 | /// 7 | /// Poor man's stackalloc: Contains a value-type buffer sized for 4 instances. 8 | /// Useful for decoder/encoder operations allocating a block for each Jpeg component. 9 | /// 10 | internal unsafe struct BlockQuad 11 | { 12 | /// 13 | /// The value-type buffer sized for 4 instances. 14 | /// 15 | public fixed float Data[4 * Block8x8F.Size]; 16 | } 17 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Encoder/GrayForwardConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace Geb.Image.Formats.Jpeg.Components.Encoder 5 | { 6 | internal unsafe struct GrayForwardConverter 7 | { 8 | /// 9 | /// The Y component 10 | /// 11 | public Block8x8F Y; 12 | 13 | /// 14 | /// Temporal 8x8 block to hold TPixel data 15 | /// 16 | private GenericBlock8x8 pixelBlock; 17 | 18 | public static GrayForwardConverter Create() 19 | { 20 | var result = default(GrayForwardConverter); 21 | return result; 22 | } 23 | 24 | /// 25 | /// Converts a 8x8 image area inside 'pixels' at position (x,y) placing the result members of the structure (, , ) 26 | /// 27 | public void Convert(ImageU8 pixels, int x, int y) 28 | { 29 | this.pixelBlock.LoadAndStretchEdges(ref Unsafe.AsRef((void*)pixels.Start), pixels.Width, pixels.Height, x, y); 30 | 31 | for (int i = 0; i < 64; i++) 32 | { 33 | this.Y[i] = pixelBlock[i]; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Encoder/HuffIndex.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Jpeg.Components.Encoder 5 | { 6 | /// 7 | /// Enumerates the Huffman tables 8 | /// 9 | internal enum HuffIndex 10 | { 11 | /// 12 | /// The DC luminance huffman table index 13 | /// 14 | LuminanceDC = 0, 15 | 16 | // ReSharper disable UnusedMember.Local 17 | 18 | /// 19 | /// The AC luminance huffman table index 20 | /// 21 | LuminanceAC = 1, 22 | 23 | /// 24 | /// The DC chrominance huffman table index 25 | /// 26 | ChrominanceDC = 2, 27 | 28 | /// 29 | /// The AC chrominance huffman table index 30 | /// 31 | ChrominanceAC = 3, 32 | 33 | // ReSharper restore UnusedMember.Local 34 | } 35 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/Encoder/QuantIndex.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Jpeg.Components.Encoder 5 | { 6 | /// 7 | /// Enumerates the quantization tables 8 | /// 9 | internal enum QuantIndex 10 | { 11 | /// 12 | /// The luminance quantization table index 13 | /// 14 | Luminance = 0, 15 | 16 | /// 17 | /// The chrominance quantization table index 18 | /// 19 | Chrominance = 1, 20 | } 21 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/GenericBlock8x8.Generated.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | // Copyright (c) Six Labors and contributors. 9 | // Licensed under the Apache License, Version 2.0. 10 | 11 | // 12 | namespace Geb.Image.Formats.Jpeg.Components 13 | { 14 | internal unsafe partial struct GenericBlock8x8 15 | { 16 | #pragma warning disable 169 17 | 18 | // It's not allowed use fix-sized buffers with generics, need to place all the fields manually: 19 | private T _y0_x0, _y0_x1, _y0_x2, _y0_x3, _y0_x4, _y0_x5, _y0_x6, _y0_x7; 20 | private T _y1_x0, _y1_x1, _y1_x2, _y1_x3, _y1_x4, _y1_x5, _y1_x6, _y1_x7; 21 | private T _y2_x0, _y2_x1, _y2_x2, _y2_x3, _y2_x4, _y2_x5, _y2_x6, _y2_x7; 22 | private T _y3_x0, _y3_x1, _y3_x2, _y3_x3, _y3_x4, _y3_x5, _y3_x6, _y3_x7; 23 | private T _y4_x0, _y4_x1, _y4_x2, _y4_x3, _y4_x4, _y4_x5, _y4_x6, _y4_x7; 24 | private T _y5_x0, _y5_x1, _y5_x2, _y5_x3, _y5_x4, _y5_x5, _y5_x6, _y5_x7; 25 | private T _y6_x0, _y6_x1, _y6_x2, _y6_x3, _y6_x4, _y6_x5, _y6_x6, _y6_x7; 26 | private T _y7_x0, _y7_x1, _y7_x2, _y7_x3, _y7_x4, _y7_x5, _y7_x6, _y7_x7; 27 | 28 | 29 | #pragma warning restore 169 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/GenericBlock8x8.Generated.tt: -------------------------------------------------------------------------------- 1 | <# 2 | // Copyright (c) Six Labors and contributors. 3 | // Licensed under the Apache License, Version 2.0. 4 | #> 5 | <#@ template debug="false" hostspecific="false" language="C#" #> 6 | <#@ assembly name="System.Core" #> 7 | <#@ import namespace="System.Linq" #> 8 | <#@ import namespace="System.Text" #> 9 | <#@ import namespace="System.Collections.Generic" #> 10 | <#@ output extension=".cs" #> 11 | // Copyright (c) Six Labors and contributors. 12 | // Licensed under the Apache License, Version 2.0. 13 | 14 | // 15 | namespace Geb.Image.Formats.Jpeg.Components 16 | { 17 | internal unsafe partial struct GenericBlock8x8 18 | { 19 | #pragma warning disable 169 20 | 21 | // It's not allowed use fix-sized buffers with generics, need to place all the fields manually: 22 | <# 23 | PushIndent(" "); 24 | Write(" "); 25 | for (int y = 0; y < 8; y++) 26 | { 27 | Write("private T "); 28 | for (int x = 0; x < 8; x++) 29 | { 30 | Write($"_y{y}_x{x}"); 31 | if (x < 7) Write(", "); 32 | } 33 | WriteLine(";"); 34 | } 35 | PopIndent(); 36 | #> 37 | 38 | #pragma warning restore 169 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Components/SizeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Numerics; 6 | 7 | namespace Geb.Image.Formats.Jpeg.Components 8 | { 9 | /// 10 | /// Extension methods for 11 | /// 12 | internal static class SizeExtensions 13 | { 14 | /// 15 | /// Multiplies 'a.Width' with 'b.Width' and 'a.Height' with 'b.Height'. 16 | /// TODO: Shouldn't we expose this as operator in SixLabors.Core? 17 | /// 18 | public static Size MultiplyBy(this Size a, Size b) => new Size(a.Width * b.Width, a.Height * b.Height); 19 | 20 | /// 21 | /// Divides 'a.Width' with 'b.Width' and 'a.Height' with 'b.Height'. 22 | /// TODO: Shouldn't we expose this as operator in SixLabors.Core? 23 | /// 24 | public static Size DivideBy(this Size a, Size b) => new Size(a.Width / b.Width, a.Height / b.Height); 25 | 26 | /// 27 | /// Divide Width and Height as real numbers and return the Ceiling. 28 | /// 29 | public static Size DivideRoundUp(this Size originalSize, int divX, int divY) 30 | { 31 | var sizeVect = new Vector2(originalSize.Width, originalSize.Height); 32 | sizeVect /= new Vector2(divX, divY); 33 | sizeVect.X = (float)Math.Ceiling(sizeVect.X); 34 | sizeVect.Y = (float)Math.Ceiling(sizeVect.Y); 35 | return new Size((int)sizeVect.X, (int)sizeVect.Y); 36 | } 37 | 38 | /// 39 | /// Divide Width and Height as real numbers and return the Ceiling. 40 | /// 41 | public static Size DivideRoundUp(this Size originalSize, int divisor) => 42 | DivideRoundUp(originalSize, divisor, divisor); 43 | 44 | /// 45 | /// Divide Width and Height as real numbers and return the Ceiling. 46 | /// 47 | public static Size DivideRoundUp(this Size originalSize, Size divisor) => 48 | DivideRoundUp(originalSize, divisor.Width, divisor.Height); 49 | } 50 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/IJpegDecoderOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Jpeg 6 | { 7 | /// 8 | /// Image decoder for generating an image out of a jpg stream. 9 | /// 10 | internal interface IJpegDecoderOptions 11 | { 12 | /// 13 | /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. 14 | /// 15 | bool IgnoreMetadata { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/IJpegEncoderOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Jpeg 6 | { 7 | /// 8 | /// Encoder for writing the data image to a stream in jpeg format. 9 | /// 10 | internal interface IJpegEncoderOptions 11 | { 12 | /// 13 | /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. 14 | /// 15 | bool IgnoreMetadata { get; } 16 | 17 | /// 18 | /// Gets the quality, that will be used to encode the image. Quality 19 | /// index must be between 0 and 100 (compression from max to min). 20 | /// 21 | /// The quality of the jpg image from 0 to 100. 22 | int Quality { get; } 23 | 24 | /// 25 | /// Gets the subsample ration, that will be used to encode the image. 26 | /// 27 | /// The subsample ratio of the jpg image. 28 | JpegSubsample? Subsample { get; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Jpeg12Encoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Jpeg 6 | { 7 | //internal class Jpeg12Encoder : BaseJpegEncoder 8 | //{ 9 | //} 10 | } 11 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/Jpeg16Encoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Jpeg 6 | { 7 | using Geb.Image.Formats.Jpeg.Components; 8 | using Geb.Image.Formats.Jpeg.Components.Encoder; 9 | 10 | internal abstract class Jpeg16Encoder : BaseJpegEncoder 11 | { 12 | public Jpeg16Encoder(int quality = 50) : base(quality, JpegPixelFormats.Gray) 13 | { 14 | } 15 | } 16 | 17 | internal unsafe class Jpeg16GrayEncoder : Jpeg16Encoder 18 | { 19 | protected override byte[] GetSosHeader() 20 | { 21 | return BaseJpegEncoder.SosHeaderGray; 22 | } 23 | 24 | protected override void WriteImageData(ImageHolder image) 25 | { 26 | ImageU8 pixels = image.GetImageU8(); 27 | 28 | Block8x8F temp1 = default; 29 | Block8x8F temp2 = default; 30 | 31 | Block8x8F onStackLuminanceQuantTable = this.luminanceQuantTable; 32 | var unzig = ZigZag.CreateUnzigTable(); 33 | GrayForwardConverter pixelConverter = GrayForwardConverter.Create(); 34 | 35 | int prevDCY = 0; 36 | for (int y = 0; y < pixels.Height; y += 8) 37 | { 38 | for (int x = 0; x < pixels.Width; x += 8) 39 | { 40 | pixelConverter.Convert(pixels, x, y); 41 | prevDCY = this.WriteBlock( 42 | QuantIndex.Luminance, 43 | prevDCY, 44 | &pixelConverter.Y, 45 | &temp1, 46 | &temp2, 47 | &onStackLuminanceQuantTable, 48 | unzig.Data); 49 | } 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/JpegDecoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats.Jpeg 7 | { 8 | using Geb.Image.Formats.Jpeg.PdfJsPort; 9 | 10 | /// 11 | /// Image decoder for generating an image out of a jpg stream. 12 | /// 13 | public sealed class JpegDecoder : IJpegDecoderOptions 14 | { 15 | /// 16 | /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. 17 | /// 18 | public bool IgnoreMetadata { get; set; } 19 | 20 | /// 21 | public ImageBgra32 Decode(Stream stream) 22 | { 23 | using (var decoder = new PdfJsJpegDecoderCore(null, this)) 24 | { 25 | return decoder.Decode(stream); 26 | } 27 | } 28 | 29 | public ImageBgra32 Decode(String filePath) 30 | { 31 | using (var decoder = new PdfJsJpegDecoderCore(null, this)) 32 | using (FileStream fs = new FileStream(filePath, FileMode.Open)) 33 | { 34 | return decoder.Decode(fs); 35 | } 36 | } 37 | 38 | /// 39 | public IImageInfo Identify(Stream stream) 40 | { 41 | using (var decoder = new PdfJsJpegDecoderCore(null, this)) 42 | { 43 | return decoder.Identify(stream); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/JpegFormat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Jpeg 6 | { 7 | /// 8 | /// Registers the image encoders, decoders and mime type detectors for the jpeg format. 9 | /// 10 | internal sealed class JpegFormat : IImageFormat 11 | { 12 | /// 13 | public string Name => "JPEG"; 14 | 15 | /// 16 | public string DefaultMimeType => "image/jpeg"; 17 | 18 | /// 19 | public IEnumerable MimeTypes => JpegConstants.MimeTypes; 20 | 21 | /// 22 | public IEnumerable FileExtensions => JpegConstants.FileExtensions; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/JpegSubsample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Jpeg 6 | { 7 | /// 8 | /// Enumerates the chroma subsampling method applied to the image. 9 | /// 10 | public enum JpegSubsample 11 | { 12 | /// 13 | /// High Quality - Each of the three Y'CbCr components have the same sample rate, 14 | /// thus there is no chroma subsampling. 15 | /// 16 | Ratio444, 17 | 18 | /// 19 | /// Medium Quality - The horizontal sampling is halved and the Cb and Cr channels are only 20 | /// sampled on each alternate line. 21 | /// 22 | Ratio420 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/PdfJsPort/Components/FixedByteBuffer256.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Geb.Image.Formats.Jpeg.PdfJsPort.Components 8 | { 9 | [StructLayout(LayoutKind.Sequential)] 10 | internal unsafe struct FixedByteBuffer256 11 | { 12 | public fixed byte Data[256]; 13 | 14 | public byte this[int idx] 15 | { 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | get 18 | { 19 | ref byte self = ref Unsafe.As(ref this); 20 | return Unsafe.Add(ref self, idx); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/PdfJsPort/Components/FixedInt16Buffer18.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Geb.Image.Formats.Jpeg.PdfJsPort.Components 8 | { 9 | [StructLayout(LayoutKind.Sequential)] 10 | internal unsafe struct FixedInt16Buffer18 11 | { 12 | public fixed short Data[18]; 13 | 14 | public short this[int idx] 15 | { 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | get 18 | { 19 | ref short self = ref Unsafe.As(ref this); 20 | return Unsafe.Add(ref self, idx); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/PdfJsPort/Components/FixedInt16Buffer256.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Geb.Image.Formats.Jpeg.PdfJsPort.Components 8 | { 9 | [StructLayout(LayoutKind.Sequential)] 10 | internal unsafe struct FixedInt16Buffer256 11 | { 12 | public fixed short Data[256]; 13 | 14 | public short this[int idx] 15 | { 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | get 18 | { 19 | ref short self = ref Unsafe.As(ref this); 20 | return Unsafe.Add(ref self, idx); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/PdfJsPort/Components/FixedInt64Buffer18.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace Geb.Image.Formats.Jpeg.PdfJsPort.Components 8 | { 9 | [StructLayout(LayoutKind.Sequential)] 10 | internal unsafe struct FixedInt64Buffer18 11 | { 12 | public fixed long Data[18]; 13 | 14 | public long this[int idx] 15 | { 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | get 18 | { 19 | ref long self = ref Unsafe.As(ref this); 20 | return Unsafe.Add(ref self, idx); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTables.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Collections.Generic; 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace Geb.Image.Formats.Jpeg.PdfJsPort.Components 8 | { 9 | /// 10 | /// Defines a 2 pairs of huffman tables 11 | /// 12 | internal sealed class PdfJsHuffmanTables 13 | { 14 | private readonly PdfJsHuffmanTable[] tables = new PdfJsHuffmanTable[4]; 15 | 16 | /// 17 | /// Gets or sets the table at the given index. 18 | /// 19 | /// The index 20 | /// The 21 | public ref PdfJsHuffmanTable this[int index] 22 | { 23 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 24 | get => ref this.tables[index]; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.IO; 5 | 6 | namespace Geb.Image.Formats.Jpeg.PdfJsPort 7 | { 8 | /// 9 | /// Image decoder for generating an image out of a jpg stream. 10 | /// 11 | internal sealed class PdfJsJpegDecoder : IJpegDecoderOptions 12 | { 13 | /// 14 | /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. 15 | /// 16 | public bool IgnoreMetadata { get; set; } 17 | 18 | /// 19 | public ImageBgra32 Decode(Configuration configuration, Stream stream) 20 | { 21 | Guard.NotNull(stream, nameof(stream)); 22 | 23 | using (var decoder = new PdfJsJpegDecoderCore(configuration, this)) 24 | { 25 | //return decoder.Decode(stream); 26 | return null; 27 | } 28 | } 29 | 30 | /// 31 | public IImageInfo Identify(Configuration configuration, Stream stream) 32 | { 33 | Guard.NotNull(stream, nameof(stream)); 34 | 35 | using (var decoder = new PdfJsJpegDecoderCore(configuration, this)) 36 | { 37 | return decoder.Identify(stream); 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/BasicArrayBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace Geb.Image.Formats 7 | { 8 | /// 9 | /// Exposes an array through the interface. 10 | /// 11 | internal class BasicArrayBuffer : IBuffer 12 | where T : struct 13 | { 14 | public BasicArrayBuffer(T[] array, int length) 15 | { 16 | DebugGuard.MustBeLessThanOrEqualTo(length, array.Length, nameof(length)); 17 | this.Array = array; 18 | this.Length = length; 19 | } 20 | 21 | public BasicArrayBuffer(T[] array) 22 | : this(array, array.Length) 23 | { 24 | } 25 | 26 | public T[] Array { get; } 27 | 28 | public int Length { get; } 29 | 30 | public Span Span => this.Array.AsSpan(0, this.Length); 31 | 32 | /// 33 | /// Returns a reference to specified element of the buffer. 34 | /// 35 | /// The index 36 | /// The reference to the specified element 37 | public ref T this[int index] 38 | { 39 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 40 | get 41 | { 42 | DebugGuard.MustBeLessThan(index, this.Length, nameof(index)); 43 | 44 | Span span = this.Span; 45 | return ref span[index]; 46 | } 47 | } 48 | 49 | public void Dispose() 50 | { 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/BasicByteBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | internal class BasicByteBuffer : BasicArrayBuffer, IManagedByteBuffer 8 | { 9 | internal BasicByteBuffer(byte[] array) 10 | : base(array) 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/IBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// 9 | /// Represents a contigous memory buffer of value-type items "promising" a 10 | /// 11 | /// The value type 12 | internal interface IBuffer : IDisposable 13 | where T : struct 14 | { 15 | /// 16 | /// Gets the span to the memory "promised" by this buffer 17 | /// 18 | Span Span { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/IBuffer2D.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// An interface that represents a pinned buffer of value type objects 9 | /// interpreted as a 2D region of x elements. 10 | /// 11 | /// The value type. 12 | internal interface IBuffer2D 13 | where T : struct 14 | { 15 | /// 16 | /// Gets the width. 17 | /// 18 | int Width { get; } 19 | 20 | /// 21 | /// Gets the height. 22 | /// 23 | int Height { get; } 24 | 25 | /// 26 | /// Gets a to the backing buffer. 27 | /// 28 | Span Span { get; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/IManagedByteBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Represents a byte buffer backed by a managed array. Useful for interop with classic .NET API-s. 9 | /// 10 | internal interface IManagedByteBuffer : IBuffer 11 | { 12 | /// 13 | /// Gets the managed array backing this buffer instance. 14 | /// 15 | byte[] Array { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/MemoryManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Memory managers are used to allocate memory for image processing operations. 9 | /// 10 | public abstract class MemoryManager 11 | { 12 | /// 13 | /// Allocates an of size , optionally 14 | /// clearing the buffer before it gets returned. 15 | /// 16 | /// Type of the data stored in the buffer 17 | /// Size of the buffer to allocate 18 | /// True to clear the backing memory of the buffer 19 | /// A buffer of values of type . 20 | internal abstract IBuffer Allocate(int length, bool clear) 21 | where T : struct; 22 | 23 | /// 24 | /// Allocates an 25 | /// 26 | /// The requested buffer length 27 | /// A value indicating whether to clean the buffer 28 | /// The 29 | internal abstract IManagedByteBuffer AllocateManagedByteBuffer(int length, bool clear); 30 | 31 | /// 32 | /// Temporal workaround. A method providing a "Buffer" based on a generic array without the 'Unsafe.As()' hackery. 33 | /// Should be replaced with 'Allocate()' as soon as SixLabors.Shapes has Span-based API-s! 34 | /// 35 | internal BasicArrayBuffer AllocateFake(int length, bool dummy = false) 36 | where T : struct 37 | { 38 | return new BasicArrayBuffer(new T[length]); 39 | } 40 | 41 | /// 42 | /// Releases all retained resources not being in use. 43 | /// Eg: by resetting array pools and letting GC to free the arrays. 44 | /// 45 | public virtual void ReleaseRetainedResources() 46 | { 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Memory/SimpleGcMemoryManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | // 8 | /// Implements by newing up arrays by the GC on every allocation requests. 9 | /// 10 | public class SimpleGcMemoryManager : MemoryManager 11 | { 12 | /// 13 | internal override IBuffer Allocate(int length, bool clear) 14 | { 15 | return new BasicArrayBuffer(new T[length]); 16 | } 17 | 18 | internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, bool clear) 19 | { 20 | return new BasicByteBuffer(new byte[length]); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/ImageFrameMetaData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using Geb.Image.Formats; 5 | using Geb.Image.Formats.Gif; 6 | 7 | namespace Geb.Image.Formats.MetaData 8 | { 9 | /// 10 | /// Encapsulates the metadata of an image frame. 11 | /// 12 | public sealed class ImageFrameMetaData 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | internal ImageFrameMetaData() 18 | { 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class 23 | /// by making a copy from other metadata. 24 | /// 25 | /// 26 | /// The other to create this instance from. 27 | /// 28 | internal ImageFrameMetaData(ImageFrameMetaData other) 29 | { 30 | DebugGuard.NotNull(other, nameof(other)); 31 | 32 | this.FrameDelay = other.FrameDelay; 33 | this.DisposalMethod = other.DisposalMethod; 34 | } 35 | 36 | /// 37 | /// Gets or sets the frame delay for animated images. 38 | /// If not 0, when utilized in Gif animation, this field specifies the number of hundredths (1/100) of a second to 39 | /// wait before continuing with the processing of the Data Stream. 40 | /// The clock starts ticking immediately after the graphic is rendered. 41 | /// 42 | public int FrameDelay { get; set; } 43 | 44 | /// 45 | /// Gets or sets the disposal method for animated images. 46 | /// Primarily used in Gif animation, this field indicates the way in which the graphic is to 47 | /// be treated after being displayed. 48 | /// 49 | public DisposalMethod DisposalMethod { get; set; } 50 | 51 | /// 52 | /// Clones this ImageFrameMetaData. 53 | /// 54 | /// The cloned instance. 55 | public ImageFrameMetaData Clone() 56 | { 57 | return new ImageFrameMetaData(this); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/Exif/ExifDataType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Exif 5 | { 6 | /// 7 | /// Specifies exif data types. 8 | /// 9 | public enum ExifDataType 10 | { 11 | /// 12 | /// Unknown 13 | /// 14 | Unknown = 0, 15 | 16 | /// 17 | /// An 8-bit unsigned integer. 18 | /// 19 | Byte = 1, 20 | 21 | /// 22 | /// An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL. 23 | /// 24 | Ascii = 2, 25 | 26 | /// 27 | /// A 16-bit (2-byte) unsigned integer. 28 | /// 29 | Short = 3, 30 | 31 | /// 32 | /// A 32-bit (4-byte) unsigned integer. 33 | /// 34 | Long = 4, 35 | 36 | /// 37 | /// Two LONGs. The first LONG is the numerator and the second LONG expresses the denominator. 38 | /// 39 | Rational = 5, 40 | 41 | /// 42 | /// An 8-bit signed integer. 43 | /// 44 | SignedByte = 6, 45 | 46 | /// 47 | /// An 8-bit byte that can take any value depending on the field definition. 48 | /// 49 | Undefined = 7, 50 | 51 | /// 52 | /// A 16-bit (2-byte) signed integer. 53 | /// 54 | SignedShort = 8, 55 | 56 | /// 57 | /// A 32-bit (4-byte) signed integer (2's complement notation). 58 | /// 59 | SignedLong = 9, 60 | 61 | /// 62 | /// Two SLONGs. The first SLONG is the numerator and the second SLONG is the denominator. 63 | /// 64 | SignedRational = 10, 65 | 66 | /// 67 | /// A 32-bit floating point value. 68 | /// 69 | SingleFloat = 11, 70 | 71 | /// 72 | /// A 64-bit floating point value. 73 | /// 74 | DoubleFloat = 12 75 | } 76 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/Exif/ExifParts.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Exif 7 | { 8 | /// 9 | /// Specifies which parts will be written when the profile is added to an image. 10 | /// 11 | [Flags] 12 | public enum ExifParts 13 | { 14 | /// 15 | /// None 16 | /// 17 | None = 0, 18 | 19 | /// 20 | /// IfdTags 21 | /// 22 | IfdTags = 1, 23 | 24 | /// 25 | /// ExifTags 26 | /// 27 | ExifTags = 4, 28 | 29 | /// 30 | /// GPSTags 31 | /// 32 | GPSTags = 8, 33 | 34 | /// 35 | /// All 36 | /// 37 | All = IfdTags | ExifTags | GPSTags 38 | } 39 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/Exif/ExifTagDescriptionAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Reflection; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Exif 8 | { 9 | /// 10 | /// Class that provides a description for an ExifTag value. 11 | /// 12 | [AttributeUsage(AttributeTargets.Field, AllowMultiple = true)] 13 | internal sealed class ExifTagDescriptionAttribute : Attribute 14 | { 15 | private object value; 16 | private string description; 17 | 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The value of the exif tag. 22 | /// The description for the value of the exif tag. 23 | public ExifTagDescriptionAttribute(object value, string description) 24 | { 25 | this.value = value; 26 | this.description = description; 27 | } 28 | 29 | /// 30 | /// Gets the tag description from any custom attributes. 31 | /// 32 | /// The tag. 33 | /// The value. 34 | /// 35 | /// The . 36 | /// 37 | public static string GetDescription(ExifTag tag, object value) 38 | { 39 | FieldInfo field = tag.GetType().GetTypeInfo().GetDeclaredField(tag.ToString()); 40 | if (field == null) 41 | { 42 | return null; 43 | } 44 | 45 | foreach (CustomAttributeData customAttribute in field.CustomAttributes) 46 | { 47 | object attributeValue = customAttribute.ConstructorArguments[0].Value; 48 | 49 | if (object.Equals(attributeValue, value)) 50 | { 51 | return (string)customAttribute.ConstructorArguments[1].Value; 52 | } 53 | } 54 | 55 | return null; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/Exif/README.md: -------------------------------------------------------------------------------- 1 | Adapted from Magick.NET: 2 | 3 | https://github.com/dlemstra/Magick.NET/tree/784e23b1f5c824fc03d4b95d3387b3efe1ed510b/Magick.NET/Core/Profiles/Exif -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Curves/IccCurveSegment.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// A segment of a curve 10 | /// 11 | internal abstract class IccCurveSegment : IEquatable 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The signature of this segment 17 | protected IccCurveSegment(IccCurveSegmentSignature signature) 18 | { 19 | this.Signature = signature; 20 | } 21 | 22 | /// 23 | /// Gets the signature of this segment 24 | /// 25 | public IccCurveSegmentSignature Signature { get; } 26 | 27 | /// 28 | public virtual bool Equals(IccCurveSegment other) 29 | { 30 | if (other == null) 31 | { 32 | return false; 33 | } 34 | 35 | if (ReferenceEquals(this, other)) 36 | { 37 | return true; 38 | } 39 | 40 | return this.Signature == other.Signature; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Curves/IccOneDimensionalCurve.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Linq; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 8 | { 9 | /// 10 | /// A one dimensional ICC curve. 11 | /// 12 | internal sealed class IccOneDimensionalCurve : IEquatable 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// The break points of this curve 18 | /// The segments of this curve 19 | public IccOneDimensionalCurve(float[] breakPoints, IccCurveSegment[] segments) 20 | { 21 | Guard.NotNull(breakPoints, nameof(breakPoints)); 22 | Guard.NotNull(segments, nameof(segments)); 23 | 24 | bool isSizeCorrect = breakPoints.Length == segments.Length - 1; 25 | Guard.IsTrue(isSizeCorrect, $"{nameof(breakPoints)},{nameof(segments)}", "Number of BreakPoints must be one less than number of Segments"); 26 | 27 | this.BreakPoints = breakPoints; 28 | this.Segments = segments; 29 | } 30 | 31 | /// 32 | /// Gets the breakpoints that separate two curve segments 33 | /// 34 | public float[] BreakPoints { get; } 35 | 36 | /// 37 | /// Gets an array of curve segments 38 | /// 39 | public IccCurveSegment[] Segments { get; } 40 | 41 | /// 42 | public bool Equals(IccOneDimensionalCurve other) 43 | { 44 | if (other == null) 45 | { 46 | return false; 47 | } 48 | 49 | if (ReferenceEquals(this, other)) 50 | { 51 | return true; 52 | } 53 | 54 | return this.BreakPoints.SequenceEqual(other.BreakPoints) 55 | && this.Segments.SequenceEqual(other.Segments); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Curves/IccSampledCurveElement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Linq; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 8 | { 9 | /// 10 | /// A sampled curve segment 11 | /// 12 | internal sealed class IccSampledCurveElement : IccCurveSegment, IEquatable 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// The curve values of this segment 18 | public IccSampledCurveElement(float[] curveEntries) 19 | : base(IccCurveSegmentSignature.SampledCurve) 20 | { 21 | Guard.NotNull(curveEntries, nameof(curveEntries)); 22 | Guard.IsTrue(curveEntries.Length > 0, nameof(curveEntries), "There must be at least one value"); 23 | 24 | this.CurveEntries = curveEntries; 25 | } 26 | 27 | /// 28 | /// Gets the curve values of this segment 29 | /// 30 | public float[] CurveEntries { get; } 31 | 32 | /// 33 | public override bool Equals(IccCurveSegment other) 34 | { 35 | if (base.Equals(other) && other is IccSampledCurveElement segment) 36 | { 37 | return this.CurveEntries.SequenceEqual(segment.CurveEntries); 38 | } 39 | 40 | return false; 41 | } 42 | 43 | /// 44 | public bool Equals(IccSampledCurveElement other) 45 | { 46 | return this.Equals((IccCurveSegment)other); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/DataReader/IccDataReader.Matrix.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Provides methods to read ICC data types 8 | /// 9 | internal sealed partial class IccDataReader 10 | { 11 | /// 12 | /// Reads a two dimensional matrix 13 | /// 14 | /// Number of values in X 15 | /// Number of values in Y 16 | /// True if the values are encoded as Single; false if encoded as Fix16 17 | /// The read matrix 18 | public float[,] ReadMatrix(int xCount, int yCount, bool isSingle) 19 | { 20 | float[,] matrix = new float[xCount, yCount]; 21 | for (int y = 0; y < yCount; y++) 22 | { 23 | for (int x = 0; x < xCount; x++) 24 | { 25 | if (isSingle) 26 | { 27 | matrix[x, y] = this.ReadSingle(); 28 | } 29 | else 30 | { 31 | matrix[x, y] = this.ReadFix16(); 32 | } 33 | } 34 | } 35 | 36 | return matrix; 37 | } 38 | 39 | /// 40 | /// Reads a one dimensional matrix 41 | /// 42 | /// Number of values 43 | /// True if the values are encoded as Single; false if encoded as Fix16 44 | /// The read matrix 45 | public float[] ReadMatrix(int yCount, bool isSingle) 46 | { 47 | float[] matrix = new float[yCount]; 48 | for (int i = 0; i < yCount; i++) 49 | { 50 | if (isSingle) 51 | { 52 | matrix[i] = this.ReadSingle(); 53 | } 54 | else 55 | { 56 | matrix[i] = this.ReadFix16(); 57 | } 58 | } 59 | 60 | return matrix; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccClutDataType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Color lookup table data type 8 | /// 9 | internal enum IccClutDataType 10 | { 11 | /// 12 | /// 32bit floating point 13 | /// 14 | Float, 15 | 16 | /// 17 | /// 8bit unsigned integer (byte) 18 | /// 19 | UInt8, 20 | 21 | /// 22 | /// 16bit unsigned integer (ushort) 23 | /// 24 | UInt16, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccColorantEncoding.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Colorant Encoding 8 | /// 9 | internal enum IccColorantEncoding : ushort 10 | { 11 | /// 12 | /// Unknown colorant encoding 13 | /// 14 | Unknown = 0x0000, 15 | 16 | /// 17 | /// ITU-R BT.709-2 colorant encoding 18 | /// 19 | ItuRBt709_2 = 0x0001, 20 | 21 | /// 22 | /// SMPTE RP145 colorant encoding 23 | /// 24 | SmpteRp145 = 0x0002, 25 | 26 | /// 27 | /// EBU Tech.3213-E colorant encoding 28 | /// 29 | EbuTech3213E = 0x0003, 30 | 31 | /// 32 | /// P22 colorant encoding 33 | /// 34 | P22 = 0x0004, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccCurveMeasurementEncodings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Curve Measurement Encodings 8 | /// 9 | internal enum IccCurveMeasurementEncodings : uint 10 | { 11 | /// 12 | /// ISO 5-3 densitometer response. This is the accepted standard for 13 | /// reflection densitometers for measuring photographic color prints 14 | /// 15 | StatusA = 0x53746141, // StaA 16 | 17 | /// 18 | /// ISO 5-3 densitometer response which is the accepted standard in 19 | /// Europe for color reflection densitometers 20 | /// 21 | StatusE = 0x53746145, // StaE 22 | 23 | /// 24 | /// ISO 5-3 densitometer response commonly referred to as narrow band 25 | /// or interference-type response. 26 | /// 27 | StatusI = 0x53746149, // StaI 28 | 29 | /// 30 | /// ISO 5-3 wide band color reflection densitometer response which is 31 | /// the accepted standard in the United States for color reflection densitometers 32 | /// 33 | StatusT = 0x53746154, // StaT 34 | 35 | /// 36 | /// ISO 5-3 densitometer response for measuring color negatives 37 | /// 38 | StatusM = 0x5374614D, // StaM 39 | 40 | /// 41 | /// DIN 16536-2 densitometer response, with no polarizing filter 42 | /// 43 | DinE = 0x434E2020, // DN 44 | 45 | /// 46 | /// DIN 16536-2 densitometer response, with polarizing filter 47 | /// 48 | DinEPol = 0x434E2050, // DNP 49 | 50 | /// 51 | /// DIN 16536-2 narrow band densitometer response, with no polarizing filter 52 | /// 53 | DinI = 0x434E4E20, // DNN 54 | 55 | /// 56 | /// DIN 16536-2 narrow band densitometer response, with polarizing filter 57 | /// 58 | DinIPol = 0x434E4E50, // DNNP 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccCurveSegmentSignature.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Curve Segment Signature 8 | /// 9 | internal enum IccCurveSegmentSignature : uint 10 | { 11 | /// 12 | /// Curve defined by a formula 13 | /// 14 | FormulaCurve = 0x70617266, // parf 15 | 16 | /// 17 | /// Curve defined by multiple segments 18 | /// 19 | SampledCurve = 0x73616D66, // samf 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccDeviceAttribute.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// Device attributes. Can be combined with a logical OR 10 | /// The least-significant 32 bits are defined by the ICC, 11 | /// the rest can be used for vendor specific values 12 | /// 13 | [Flags] 14 | public enum IccDeviceAttribute : long 15 | { 16 | /// 17 | /// Opacity transparent 18 | /// 19 | OpacityTransparent = 1 << 0, 20 | 21 | /// 22 | /// Opacity reflective 23 | /// 24 | OpacityReflective = 0, 25 | 26 | /// 27 | /// Reflectivity matte 28 | /// 29 | ReflectivityMatte = 1 << 1, 30 | 31 | /// 32 | /// Reflectivity glossy 33 | /// 34 | ReflectivityGlossy = 0, 35 | 36 | /// 37 | /// Polarity negative 38 | /// 39 | PolarityNegative = 1 << 2, 40 | 41 | /// 42 | /// Polarity positive 43 | /// 44 | PolarityPositive = 0, 45 | 46 | /// 47 | /// Chroma black and white 48 | /// 49 | ChromaBlackWhite = 1 << 3, 50 | 51 | /// 52 | /// Chroma color 53 | /// 54 | ChromaColor = 0, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccFormulaCurveType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Formula curve segment type 8 | /// 9 | internal enum IccFormulaCurveType : ushort 10 | { 11 | /// 12 | /// Type 1: Y = (a * X + b)^γ + c 13 | /// 14 | Type1 = 0, 15 | 16 | /// 17 | /// Type 1: Y = a * log10 (b * X^γ + c) + d 18 | /// 19 | Type2 = 1, 20 | 21 | /// 22 | /// Type 3: Y = a * b^(c * X + d) + e 23 | /// 24 | Type3 = 2 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccMeasurementGeometry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Measurement Geometry 8 | /// 9 | internal enum IccMeasurementGeometry : uint 10 | { 11 | /// 12 | /// Unknown geometry 13 | /// 14 | Unknown = 0, 15 | 16 | /// 17 | /// Geometry of 0°:45° or 45°:0° 18 | /// 19 | Degree0To45Or45To0 = 1, 20 | 21 | /// 22 | /// Geometry of 0°:d or d:0° 23 | /// 24 | Degree0ToDOrDTo0 = 2, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccMultiProcessElementSignature.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Multi process element signature 8 | /// 9 | internal enum IccMultiProcessElementSignature : uint 10 | { 11 | /// 12 | /// Set of curves 13 | /// 14 | CurveSet = 0x6D666C74, // cvst 15 | 16 | /// 17 | /// Matrix transformation 18 | /// 19 | Matrix = 0x6D617466, // matf 20 | 21 | /// 22 | /// Color lookup table 23 | /// 24 | Clut = 0x636C7574, // clut 25 | 26 | /// 27 | /// Reserved for future expansion. Do not use! 28 | /// 29 | BAcs = 0x62414353, // bACS 30 | 31 | /// 32 | /// Reserved for future expansion. Do not use! 33 | /// 34 | EAcs = 0x65414353, // eACS 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccParametricCurveType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Formula curve segment type 8 | /// 9 | internal enum IccParametricCurveType : ushort 10 | { 11 | /// 12 | /// Type 1: Y = X^g 13 | /// 14 | Type1 = 0, 15 | 16 | /// 17 | /// CIE 122-1996: 18 | /// For X >= -b/a: Y =(a * X + b)^g 19 | /// For X $lt; -b/a: Y = 0 20 | /// 21 | Cie122_1996 = 1, 22 | 23 | /// 24 | /// IEC 61966-3: 25 | /// For X >= -b/a: Y =(a * X + b)^g + c 26 | /// For X $lt; -b/a: Y = c 27 | /// 28 | Iec61966_3 = 2, 29 | 30 | /// 31 | /// IEC 61966-2-1 (sRGB): 32 | /// For X >= d: Y =(a * X + b)^g 33 | /// For X $lt; d: Y = c * X 34 | /// 35 | SRgb = 3, 36 | 37 | /// 38 | /// Type 5: 39 | /// For X >= d: Y =(a * X + b)^g + c 40 | /// For X $lt; d: Y = c * X + f 41 | /// 42 | Type5 = 4, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccPrimaryPlatformType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Enumerates the primary platform/operating system framework for which the profile was created 8 | /// 9 | public enum IccPrimaryPlatformType : uint 10 | { 11 | /// 12 | /// No platform identified 13 | /// 14 | NotIdentified = 0x00000000, 15 | 16 | /// 17 | /// Apple Computer, Inc. 18 | /// 19 | AppleComputerInc = 0x4150504C, // APPL 20 | 21 | /// 22 | /// Microsoft Corporation 23 | /// 24 | MicrosoftCorporation = 0x4D534654, // MSFT 25 | 26 | /// 27 | /// Silicon Graphics, Inc. 28 | /// 29 | SiliconGraphicsInc = 0x53474920, // SGI 30 | 31 | /// 32 | /// Sun Microsystems, Inc. 33 | /// 34 | SunMicrosystemsInc = 0x53554E57, // SUNW 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccProfileFlag.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// Profile flags. Can be combined with a logical OR. 10 | /// The least-significant 16 bits are reserved for the ICC, 11 | /// the rest can be used for vendor specific values 12 | /// 13 | [Flags] 14 | public enum IccProfileFlag : int 15 | { 16 | /// 17 | /// No flags (equivalent to NotEmbedded and Independent) 18 | /// 19 | None = 0, 20 | 21 | /// 22 | /// Profile is embedded within another file 23 | /// 24 | Embedded = 1 << 0, 25 | 26 | /// 27 | /// Profile is embedded within another file 28 | /// 29 | NotEmbedded = 0, 30 | 31 | /// 32 | /// Profile cannot be used independently of the embedded colour data 33 | /// 34 | NotIndependent = 1 << 1, 35 | 36 | /// 37 | /// Profile can be used independently of the embedded colour data 38 | /// 39 | Independent = 0, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccRenderingIntent.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Rendering intent 8 | /// 9 | public enum IccRenderingIntent : uint 10 | { 11 | /// 12 | /// In perceptual transforms the PCS values represent hypothetical 13 | /// measurements of a colour reproduction on the reference reflective 14 | /// medium. By extension, for the perceptual intent, the PCS represents 15 | /// the appearance of that reproduction as viewed in the reference viewing 16 | /// environment by a human observer adapted to that environment. The exact 17 | /// colour rendering of the perceptual intent is vendor specific. 18 | /// 19 | Perceptual = 0, 20 | 21 | /// 22 | /// Transformations for this intent shall re-scale the in-gamut, 23 | /// chromatically adapted tristimulus values such that the white 24 | /// point of the actual medium is mapped to the PCS white point 25 | /// (for either input or output) 26 | /// 27 | MediaRelativeColorimetric = 1, 28 | 29 | /// 30 | /// The exact colour rendering of the saturation intent is vendor 31 | /// specific and involves compromises such as trading off 32 | /// preservation of hue in order to preserve the vividness of pure colours. 33 | /// 34 | Saturation = 2, 35 | 36 | /// 37 | /// Transformations for this intent shall leave the chromatically 38 | /// adapted nCIEXYZ tristimulus values of the in-gamut colours unchanged. 39 | /// 40 | AbsoluteColorimetric = 3, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccScreeningFlag.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// Screening flags. Can be combined with a logical OR. 10 | /// 11 | [Flags] 12 | internal enum IccScreeningFlag : int 13 | { 14 | /// 15 | /// No flags (equivalent to NotDefaultScreens and UnitLinesPerCm) 16 | /// 17 | None = 0, 18 | 19 | /// 20 | /// Use printer default screens 21 | /// 22 | DefaultScreens = 1 << 0, 23 | 24 | /// 25 | /// Don't use printer default screens 26 | /// 27 | NotDefaultScreens = 0, 28 | 29 | /// 30 | /// Frequency units in Lines/Inch 31 | /// 32 | UnitLinesPerInch = 1 << 1, 33 | 34 | /// 35 | /// Frequency units in Lines/cm 36 | /// 37 | UnitLinesPerCm = 0, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccScreeningSpotType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Enumerates the screening spot types 8 | /// 9 | internal enum IccScreeningSpotType : int 10 | { 11 | /// 12 | /// Unknown spot type 13 | /// 14 | Unknown = 0, 15 | 16 | /// 17 | /// Default printer spot type 18 | /// 19 | PrinterDefault = 1, 20 | 21 | /// 22 | /// Round stop type 23 | /// 24 | Round = 2, 25 | 26 | /// 27 | /// Diamond spot type 28 | /// 29 | Diamond = 3, 30 | 31 | /// 32 | /// Ellipse spot type 33 | /// 34 | Ellipse = 4, 35 | 36 | /// 37 | /// Line spot type 38 | /// 39 | Line = 5, 40 | 41 | /// 42 | /// Square spot type 43 | /// 44 | Square = 6, 45 | 46 | /// 47 | /// Cross spot type 48 | /// 49 | Cross = 7, 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccStandardIlluminant.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Standard Illuminant 8 | /// 9 | internal enum IccStandardIlluminant : uint 10 | { 11 | /// 12 | /// Unknown illuminant 13 | /// 14 | Unknown = 0, 15 | 16 | /// 17 | /// D50 illuminant 18 | /// 19 | D50 = 1, 20 | 21 | /// 22 | /// D65 illuminant 23 | /// 24 | D65 = 2, 25 | 26 | /// 27 | /// D93 illuminant 28 | /// 29 | D93 = 3, 30 | 31 | /// 32 | /// F2 illuminant 33 | /// 34 | F2 = 4, 35 | 36 | /// 37 | /// D55 illuminant 38 | /// 39 | D55 = 5, 40 | 41 | /// 42 | /// A illuminant 43 | /// 44 | A = 6, 45 | 46 | /// 47 | /// D50 illuminant 48 | /// 49 | EquiPowerE = 7, 50 | 51 | /// 52 | /// F8 illuminant 53 | /// 54 | F8 = 8, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Enums/IccStandardObserver.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 5 | { 6 | /// 7 | /// Standard Observer 8 | /// 9 | internal enum IccStandardObserver : uint 10 | { 11 | /// 12 | /// Unknown observer 13 | /// 14 | Unkown = 0, 15 | 16 | /// 17 | /// CIE 1931 observer 18 | /// 19 | Cie1931Observer = 1, 20 | 21 | /// 22 | /// CIE 1964 observer 23 | /// 24 | Cie1964Observer = 2, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Exceptions/InvalidIccProfileException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// Represents an error that happened while reading or writing a corrupt/invalid ICC profile 10 | /// 11 | public class InvalidIccProfileException : Exception 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The message that describes the error 17 | public InvalidIccProfileException(string message) 18 | : base(message) 19 | { 20 | } 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The message that describes the error 26 | /// The exception that is the cause of the current exception, or a null reference 27 | /// (Nothing in Visual Basic) if no inner exception is specified 28 | public InvalidIccProfileException(string message, Exception inner) 29 | : base(message, inner) 30 | { 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/MultiProcessElements/IccBAcsProcessElement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// A placeholder (might be used for future ICC versions) 10 | /// 11 | internal sealed class IccBAcsProcessElement : IccMultiProcessElement, IEquatable 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// Number of input channels 17 | /// Number of output channels 18 | public IccBAcsProcessElement(int inChannelCount, int outChannelCount) 19 | : base(IccMultiProcessElementSignature.BAcs, inChannelCount, outChannelCount) 20 | { 21 | } 22 | 23 | /// 24 | public bool Equals(IccBAcsProcessElement other) 25 | { 26 | return base.Equals(other); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/MultiProcessElements/IccClutProcessElement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// A CLUT (color lookup table) element to process data 10 | /// 11 | internal sealed class IccClutProcessElement : IccMultiProcessElement, IEquatable 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The color lookup table of this element 17 | public IccClutProcessElement(IccClut clutValue) 18 | : base(IccMultiProcessElementSignature.Clut, clutValue?.InputChannelCount ?? 1, clutValue?.OutputChannelCount ?? 1) 19 | { 20 | Guard.NotNull(clutValue, nameof(clutValue)); 21 | this.ClutValue = clutValue; 22 | } 23 | 24 | /// 25 | /// Gets the color lookup table of this element 26 | /// 27 | public IccClut ClutValue { get; } 28 | 29 | /// 30 | public override bool Equals(IccMultiProcessElement other) 31 | { 32 | if (base.Equals(other) && other is IccClutProcessElement element) 33 | { 34 | return this.ClutValue.Equals(element.ClutValue); 35 | } 36 | 37 | return false; 38 | } 39 | 40 | /// 41 | public bool Equals(IccClutProcessElement other) 42 | { 43 | return this.Equals((IccMultiProcessElement)other); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Linq; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 8 | { 9 | /// 10 | /// A set of curves to process data 11 | /// 12 | internal sealed class IccCurveSetProcessElement : IccMultiProcessElement, IEquatable 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// An array with one dimensional curves 18 | public IccCurveSetProcessElement(IccOneDimensionalCurve[] curves) 19 | : base(IccMultiProcessElementSignature.CurveSet, curves?.Length ?? 1, curves?.Length ?? 1) 20 | { 21 | Guard.NotNull(curves, nameof(curves)); 22 | this.Curves = curves; 23 | } 24 | 25 | /// 26 | /// Gets an array of one dimensional curves 27 | /// 28 | public IccOneDimensionalCurve[] Curves { get; } 29 | 30 | /// 31 | public override bool Equals(IccMultiProcessElement other) 32 | { 33 | if (base.Equals(other) && other is IccCurveSetProcessElement element) 34 | { 35 | return this.Curves.SequenceEqual(element.Curves); 36 | } 37 | 38 | return false; 39 | } 40 | 41 | /// 42 | public bool Equals(IccCurveSetProcessElement other) 43 | { 44 | return this.Equals((IccMultiProcessElement)other); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/MultiProcessElements/IccEAcsProcessElement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// A placeholder (might be used for future ICC versions) 10 | /// 11 | internal sealed class IccEAcsProcessElement : IccMultiProcessElement, IEquatable 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// Number of input channels 17 | /// Number of output channels 18 | public IccEAcsProcessElement(int inChannelCount, int outChannelCount) 19 | : base(IccMultiProcessElementSignature.EAcs, inChannelCount, outChannelCount) 20 | { 21 | } 22 | 23 | /// 24 | public bool Equals(IccEAcsProcessElement other) 25 | { 26 | return base.Equals(other); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/MultiProcessElements/IccMultiProcessElement.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 7 | { 8 | /// 9 | /// An element to process data 10 | /// 11 | internal abstract class IccMultiProcessElement : IEquatable 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The signature of this element 17 | /// Number of input channels 18 | /// Number of output channels 19 | protected IccMultiProcessElement(IccMultiProcessElementSignature signature, int inChannelCount, int outChannelCount) 20 | { 21 | Guard.MustBeBetweenOrEqualTo(inChannelCount, 1, 15, nameof(inChannelCount)); 22 | Guard.MustBeBetweenOrEqualTo(outChannelCount, 1, 15, nameof(outChannelCount)); 23 | 24 | this.Signature = signature; 25 | this.InputChannelCount = inChannelCount; 26 | this.OutputChannelCount = outChannelCount; 27 | } 28 | 29 | /// 30 | /// Gets the signature of this element, 31 | /// 32 | public IccMultiProcessElementSignature Signature { get; } 33 | 34 | /// 35 | /// Gets the number of input channels 36 | /// 37 | public int InputChannelCount { get; } 38 | 39 | /// 40 | /// Gets the number of output channels. 41 | /// 42 | public int OutputChannelCount { get; } 43 | 44 | /// 45 | public virtual bool Equals(IccMultiProcessElement other) 46 | { 47 | if (other == null) 48 | { 49 | return false; 50 | } 51 | 52 | if (ReferenceEquals(this, other)) 53 | { 54 | return true; 55 | } 56 | 57 | return this.Signature == other.Signature 58 | && this.InputChannelCount == other.InputChannelCount 59 | && this.OutputChannelCount == other.OutputChannelCount; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Numerics; 7 | 8 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 9 | { 10 | /// 11 | /// The XYZType contains an array of XYZ values. 12 | /// 13 | internal sealed class IccXyzTagDataEntry : IccTagDataEntry, IEquatable 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | /// The XYZ numbers 19 | public IccXyzTagDataEntry(Vector3[] data) 20 | : this(data, IccProfileTag.Unknown) 21 | { 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | /// The XYZ numbers 28 | /// Tag Signature 29 | public IccXyzTagDataEntry(Vector3[] data, IccProfileTag tagSignature) 30 | : base(IccTypeSignature.Xyz, tagSignature) 31 | { 32 | Guard.NotNull(data, nameof(data)); 33 | this.Data = data; 34 | } 35 | 36 | /// 37 | /// Gets the XYZ numbers 38 | /// 39 | public Vector3[] Data { get; } 40 | 41 | /// 42 | public override bool Equals(IccTagDataEntry other) 43 | { 44 | if (base.Equals(other) && other is IccXyzTagDataEntry entry) 45 | { 46 | return this.Data.SequenceEqual(entry.Data); 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /// 53 | public bool Equals(IccXyzTagDataEntry other) 54 | { 55 | return this.Equals((IccTagDataEntry)other); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Various/IccLocalizedString.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Globalization; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 8 | { 9 | /// 10 | /// A string with a specific locale. 11 | /// 12 | internal readonly struct IccLocalizedString : IEquatable 13 | { 14 | /// 15 | /// Initializes a new instance of the struct. 16 | /// The culture will be 17 | /// 18 | /// The text value of this string 19 | public IccLocalizedString(string text) 20 | : this(CultureInfo.CurrentCulture, text) 21 | { 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the struct. 26 | /// The culture will be 27 | /// 28 | /// The culture of this string 29 | /// The text value of this string 30 | public IccLocalizedString(CultureInfo culture, string text) 31 | { 32 | Guard.NotNull(culture, nameof(culture)); 33 | Guard.NotNull(text, nameof(text)); 34 | 35 | this.Culture = culture; 36 | this.Text = text; 37 | } 38 | 39 | /// 40 | /// Gets the text value. 41 | /// 42 | public string Text { get; } 43 | 44 | /// 45 | /// Gets the culture of text. 46 | /// 47 | public CultureInfo Culture { get; } 48 | 49 | /// 50 | public bool Equals(IccLocalizedString other) => 51 | this.Culture.Equals(other.Culture) && 52 | this.Text == other.Text; 53 | 54 | /// 55 | public override string ToString() 56 | { 57 | return $"{this.Culture.Name}: {this.Text}"; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Various/IccLut.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Linq; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 8 | { 9 | /// 10 | /// Lookup Table 11 | /// 12 | internal readonly struct IccLut : IEquatable 13 | { 14 | /// 15 | /// Initializes a new instance of the struct. 16 | /// 17 | /// The LUT values 18 | public IccLut(float[] values) 19 | { 20 | Guard.NotNull(values, nameof(values)); 21 | this.Values = values; 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the struct. 26 | /// 27 | /// The LUT values 28 | public IccLut(ushort[] values) 29 | { 30 | Guard.NotNull(values, nameof(values)); 31 | 32 | const float max = ushort.MaxValue; 33 | 34 | this.Values = new float[values.Length]; 35 | for (int i = 0; i < values.Length; i++) 36 | { 37 | this.Values[i] = values[i] / max; 38 | } 39 | } 40 | 41 | /// 42 | /// Initializes a new instance of the struct. 43 | /// 44 | /// The LUT values 45 | public IccLut(byte[] values) 46 | { 47 | Guard.NotNull(values, nameof(values)); 48 | 49 | const float max = byte.MaxValue; 50 | 51 | this.Values = new float[values.Length]; 52 | for (int i = 0; i < values.Length; i++) 53 | { 54 | this.Values[i] = values[i] / max; 55 | } 56 | } 57 | 58 | /// 59 | /// Gets the values that make up this table 60 | /// 61 | public float[] Values { get; } 62 | 63 | /// 64 | public bool Equals(IccLut other) 65 | { 66 | if (ReferenceEquals(this.Values, other.Values)) 67 | { 68 | return true; 69 | } 70 | 71 | return this.Values.SequenceEqual(other.Values); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Linq; 6 | 7 | namespace Geb.Image.Formats.MetaData.Profiles.Icc 8 | { 9 | /// 10 | /// Description of a profile within a sequence. 11 | /// 12 | internal readonly struct IccProfileSequenceIdentifier : IEquatable 13 | { 14 | /// 15 | /// Initializes a new instance of the struct. 16 | /// 17 | /// ID of the profile 18 | /// Description of the profile 19 | public IccProfileSequenceIdentifier(IccProfileId id, IccLocalizedString[] description) 20 | { 21 | Guard.NotNull(description, nameof(description)); 22 | 23 | this.Id = id; 24 | this.Description = description; 25 | } 26 | 27 | /// 28 | /// Gets the ID of the profile. 29 | /// 30 | public IccProfileId Id { get; } 31 | 32 | /// 33 | /// Gets the description of the profile. 34 | /// 35 | public IccLocalizedString[] Description { get; } 36 | 37 | /// 38 | public bool Equals(IccProfileSequenceIdentifier other) => 39 | this.Id.Equals(other.Id) && 40 | this.Description.SequenceEqual(other.Description); 41 | 42 | /// 43 | public override bool Equals(object obj) 44 | { 45 | return obj is IccProfileSequenceIdentifier other && this.Equals(other); 46 | } 47 | 48 | /// 49 | public override int GetHashCode() 50 | { 51 | unchecked 52 | { 53 | return (this.Id.GetHashCode() * 397) ^ (this.Description?.GetHashCode() ?? 0); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/PixelTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Contains information about the pixels that make up an images visual data. 9 | /// 10 | public class PixelTypeInfo 11 | { 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | /// Color depth, in number of bits per pixel. 16 | internal PixelTypeInfo(int bitsPerPixel) 17 | { 18 | this.BitsPerPixel = bitsPerPixel; 19 | } 20 | 21 | /// 22 | /// Gets color depth, in number of bits per pixel. 23 | /// 24 | public int BitsPerPixel { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/Filters/FilterType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Png.Filters 5 | { 6 | /// 7 | /// Provides enumeration of the various PNG filter types. 8 | /// 9 | /// 10 | internal enum FilterType 11 | { 12 | /// 13 | /// With the None filter, the scanline is transmitted unmodified; it is only necessary to 14 | /// insert a filter type byte before the data. 15 | /// 16 | None = 0, 17 | 18 | /// 19 | /// The Sub filter transmits the difference between each byte and the value of the corresponding 20 | /// byte of the prior pixel. 21 | /// 22 | Sub = 1, 23 | 24 | /// 25 | /// The Up filter is just like the Sub filter except that the pixel immediately above the current 26 | /// pixel, rather than just to its left, is used as the predictor. 27 | /// 28 | Up = 2, 29 | 30 | /// 31 | /// The Average filter uses the average of the two neighboring pixels (left and above) to 32 | /// predict the value of a pixel. 33 | /// 34 | Average = 3, 35 | 36 | /// 37 | /// The Paeth filter computes a simple linear function of the three neighboring pixels (left, above, upper left), 38 | /// then chooses as predictor the neighboring pixel closest to the computed value. 39 | /// This technique is due to Alan W. Paeth 40 | /// 41 | Paeth = 4 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/Filters/NoneFilter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace Geb.Image.Formats.Png.Filters 8 | { 9 | /// 10 | /// The None filter, the scanline is transmitted unmodified; it is only necessary to 11 | /// insert a filter type byte before the data. 12 | /// 13 | /// 14 | internal static class NoneFilter 15 | { 16 | /// 17 | /// Encodes the scanline 18 | /// 19 | /// The scanline to encode 20 | /// The filtered scanline result. 21 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 22 | public static void Encode(ReadOnlySpan scanline, Span result) 23 | { 24 | // Insert a byte before the data. 25 | result[0] = 0; 26 | result = result.Slice(1); 27 | scanline.Slice(0, Math.Min(scanline.Length, result.Length)).CopyTo(result); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/IPngDecoderOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats.Png 7 | { 8 | /// 9 | /// The optioas for decoding png images 10 | /// 11 | internal interface IPngDecoderOptions 12 | { 13 | /// 14 | /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. 15 | /// 16 | bool IgnoreMetadata { get; } 17 | 18 | /// 19 | /// Gets the encoding that should be used when reading text chunks. 20 | /// 21 | Encoding TextEncoding { get; } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngChunk.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Png 5 | { 6 | /// 7 | /// Stores header information about a chunk. 8 | /// 9 | internal readonly struct PngChunk 10 | { 11 | public PngChunk(int length, PngChunkType type, IManagedByteBuffer data = null, uint crc = 0) 12 | { 13 | this.Length = length; 14 | this.Type = type; 15 | this.Data = data; 16 | this.Crc = crc; 17 | } 18 | 19 | /// 20 | /// Gets the length. 21 | /// An unsigned integer giving the number of bytes in the chunk's 22 | /// data field. The length counts only the data field, not itself, 23 | /// the chunk type code, or the CRC. Zero is a valid length 24 | /// 25 | public int Length { get; } 26 | 27 | /// 28 | /// Gets the chunk type. 29 | /// The value is the equal to the UInt32BigEndian encoding of its 4 ASCII characters. 30 | /// 31 | public PngChunkType Type { get; } 32 | 33 | /// 34 | /// Gets the data bytes appropriate to the chunk type, if any. 35 | /// This field can be of zero length or null. 36 | /// 37 | public IManagedByteBuffer Data { get; } 38 | 39 | /// 40 | /// Gets a CRC (Cyclic Redundancy Check) calculated on the preceding bytes in the chunk, 41 | /// including the chunk type code and chunk data fields, but not including the length field. 42 | /// The CRC is always present, even for chunks containing no data 43 | /// 44 | public uint Crc { get; } 45 | 46 | /// 47 | /// Gets a value indicating whether the given chunk is critical to decoding 48 | /// 49 | public bool IsCritical => 50 | this.Type == PngChunkType.Header || 51 | this.Type == PngChunkType.Palette || 52 | this.Type == PngChunkType.Data || 53 | this.Type == PngChunkType.End; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngChunkType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Png 5 | { 6 | /// 7 | /// Contains a list of of chunk types. 8 | /// 9 | internal enum PngChunkType : uint 10 | { 11 | /// 12 | /// The first chunk in a png file. Can only exists once. Contains 13 | /// common information like the width and the height of the image or 14 | /// the used compression method. 15 | /// 16 | Header = 0x49484452U, // IHDR 17 | 18 | /// 19 | /// The PLTE chunk contains from 1 to 256 palette entries, each a three byte 20 | /// series in the RGB format. 21 | /// 22 | Palette = 0x504C5445U, // PLTE 23 | 24 | /// 25 | /// The IDAT chunk contains the actual image data. The image can contains more 26 | /// than one chunk of this type. All chunks together are the whole image. 27 | /// 28 | Data = 0x49444154U, // IDAT 29 | 30 | /// 31 | /// This chunk must appear last. It marks the end of the PNG data stream. 32 | /// The chunk's data field is empty. 33 | /// 34 | End = 0x49454E44U, // IEND 35 | 36 | /// 37 | /// This chunk specifies that the image uses simple transparency: 38 | /// either alpha values associated with palette entries (for indexed-color images) 39 | /// or a single transparent color (for grayscale and true color images). 40 | /// 41 | PaletteAlpha = 0x74524E53U, // tRNS 42 | 43 | /// 44 | /// Textual information that the encoder wishes to record with the image can be stored in 45 | /// tEXt chunks. Each tEXt chunk contains a keyword and a text string. 46 | /// 47 | Text = 0x74455874U, // tEXt 48 | 49 | /// 50 | /// This chunk specifies the relationship between the image samples and the desired 51 | /// display output intensity. 52 | /// 53 | Gamma = 0x67414D41U, // gAMA 54 | 55 | /// 56 | /// The pHYs chunk specifies the intended pixel size or aspect ratio for display of the image. 57 | /// 58 | Physical = 0x70485973U // pHYs 59 | } 60 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngColorType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Png 5 | { 6 | /// 7 | /// Provides enumeration of available PNG color types. 8 | /// 9 | public enum PngColorType : byte 10 | { 11 | /// 12 | /// Each pixel is a grayscale sample. 13 | /// 14 | Grayscale = 0, 15 | 16 | /// 17 | /// Each pixel is an R,G,B triple. 18 | /// 19 | Rgb = 2, 20 | 21 | /// 22 | /// Each pixel is a palette index; a PLTE chunk must appear. 23 | /// 24 | Palette = 3, 25 | 26 | /// 27 | /// Each pixel is a grayscale sample, followed by an alpha sample. 28 | /// 29 | GrayscaleWithAlpha = 4, 30 | 31 | /// 32 | /// Each pixel is an R,G,B triple, followed by an alpha sample. 33 | /// 34 | RgbWithAlpha = 6 35 | } 36 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngConfigurationModule.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Png 5 | { 6 | /// 7 | /// Registers the image encoders, decoders and mime type detectors for the png format. 8 | /// 9 | public sealed class PngConfigurationModule : IConfigurationModule 10 | { 11 | /// 12 | public void Configure(Configuration config) 13 | { 14 | //config.ImageFormatsManager.SetEncoder(ImageFormats.Png, new PngEncoder()); 15 | //config.ImageFormatsManager.SetDecoder(ImageFormats.Png, new PngDecoder()); 16 | //config.ImageFormatsManager.AddImageFormatDetector(new PngImageFormatDetector()); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngConstants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Geb.Image.Formats.Png 8 | { 9 | /// 10 | /// Defines png constants defined in the specification. 11 | /// 12 | internal static class PngConstants 13 | { 14 | /// 15 | /// The default encoding for text metadata. 16 | /// 17 | public static readonly Encoding DefaultEncoding = Encoding.GetEncoding("ASCII"); 18 | 19 | /// 20 | /// The list of mimetypes that equate to a png. 21 | /// 22 | public static readonly IEnumerable MimeTypes = new[] { "image/png" }; 23 | 24 | /// 25 | /// The list of file extensions that equate to a png. 26 | /// 27 | public static readonly IEnumerable FileExtensions = new[] { "png" }; 28 | 29 | public static readonly byte[] HeaderBytes = { 30 | 0x89, // Set the high bit. 31 | 0x50, // P 32 | 0x4E, // N 33 | 0x47, // G 34 | 0x0D, // Line ending CRLF 35 | 0x0A, // Line ending CRLF 36 | 0x1A, // EOF 37 | 0x0A // LF 38 | }; 39 | 40 | /// 41 | /// The header bytes as a big endian coded ulong. 42 | /// 43 | public const ulong HeaderValue = 0x89504E470D0A1A0AUL; 44 | } 45 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngFilterMethod.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Png 6 | { 7 | /// 8 | /// Provides enumeration of available PNG filter methods. 9 | /// 10 | public enum PngFilterMethod 11 | { 12 | /// 13 | /// With the None filter, the scanline is transmitted unmodified. 14 | /// 15 | None, 16 | 17 | /// 18 | /// The Sub filter transmits the difference between each byte and the value of the corresponding 19 | /// byte of the prior pixel. 20 | /// 21 | Sub, 22 | 23 | /// 24 | /// The Up filter is just like the filter except that the pixel immediately above the current pixel, 25 | /// rather than just to its left, is used as the predictor. 26 | /// 27 | Up, 28 | 29 | /// 30 | /// The Average filter uses the average of the two neighboring pixels (left and above) to predict the value of a pixel. 31 | /// 32 | Average, 33 | 34 | /// 35 | /// The Paeth filter computes a simple linear function of the three neighboring pixels (left, above, upper left), 36 | /// then chooses as predictor the neighboring pixel closest to the computed value. 37 | /// 38 | Paeth, 39 | 40 | /// 41 | /// Computes the output scanline using all five filters, and selects the filter that gives the smallest sum of 42 | /// absolute values of outputs. 43 | /// This method usually outperforms any single fixed filter choice. 44 | /// 45 | Adaptive, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngFormat.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System.Collections.Generic; 5 | 6 | namespace Geb.Image.Formats.Png 7 | { 8 | /// 9 | /// Registers the image encoders, decoders and mime type detectors for the png format. 10 | /// 11 | internal sealed class PngFormat : IImageFormat 12 | { 13 | /// 14 | public string Name => "PNG"; 15 | 16 | /// 17 | public string DefaultMimeType => "image/png"; 18 | 19 | /// 20 | public IEnumerable MimeTypes => PngConstants.MimeTypes; 21 | 22 | /// 23 | public IEnumerable FileExtensions => PngConstants.FileExtensions; 24 | } 25 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngImageFormatDetector.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | using System.Buffers.Binary; 6 | 7 | namespace Geb.Image.Formats.Png 8 | { 9 | /// 10 | /// Detects png file headers 11 | /// 12 | public sealed class PngImageFormatDetector : IImageFormatDetector 13 | { 14 | /// 15 | public int HeaderSize => 8; 16 | 17 | /// 18 | public IImageFormat DetectFormat(ReadOnlySpan header) 19 | { 20 | if (this.IsSupportedFileFormat(header)) 21 | { 22 | return ImageFormats.Png; 23 | } 24 | 25 | return null; 26 | } 27 | 28 | private bool IsSupportedFileFormat(ReadOnlySpan header) 29 | { 30 | return header.Length >= this.HeaderSize && BinaryPrimitives.ReadUInt64BigEndian(header) == PngConstants.HeaderValue; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/PngInterlaceMode.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | namespace Geb.Image.Formats.Png 5 | { 6 | /// 7 | /// Provides enumeration of available PNG interlace modes. 8 | /// 9 | internal enum PngInterlaceMode : byte 10 | { 11 | /// 12 | /// Non interlaced 13 | /// 14 | None = 0, 15 | 16 | /// 17 | /// Adam 7 interlacing. 18 | /// 19 | Adam7 = 1 20 | } 21 | } -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/README.md: -------------------------------------------------------------------------------- 1 | Encoder/Decoder adapted from: 2 | 3 | https://github.com/yufeih/Nine.Imaging/ 4 | https://imagetools.codeplex.com/ 5 | https://github.com/leonbloy/pngcs 6 | 7 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/Zlib/IChecksum.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Six Labors and contributors. 2 | // Licensed under the Apache License, Version 2.0. 3 | 4 | using System; 5 | 6 | namespace Geb.Image.Formats.Png.Zlib 7 | { 8 | /// 9 | /// Interface to compute a data checksum used by checked input/output streams. 10 | /// A data checksum can be updated by one byte or with a byte array. After each 11 | /// update the value of the current checksum can be returned by calling 12 | /// Value. The complete checksum object can also be reset 13 | /// so it can be used again with new data. 14 | /// 15 | internal interface IChecksum 16 | { 17 | /// 18 | /// Gets the data checksum computed so far. 19 | /// 20 | long Value { get; } 21 | 22 | /// 23 | /// Resets the data checksum as if no update was ever called. 24 | /// 25 | void Reset(); 26 | 27 | /// 28 | /// Adds one byte to the data checksum. 29 | /// 30 | /// 31 | /// The data value to add. The high byte of the integer is ignored. 32 | /// 33 | void Update(int value); 34 | 35 | /// 36 | /// Updates the data checksum with the bytes taken from the span. 37 | /// 38 | /// 39 | /// buffer an array of bytes 40 | /// 41 | void Update(ReadOnlySpan data); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Png/Zlib/README.md: -------------------------------------------------------------------------------- 1 | Adler32.cs and Crc32.cs have been copied from 2 | https://github.com/ygrenier/SharpZipLib.Portable 3 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Quantization/IQuantizer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats.Quantization 6 | { 7 | /// 8 | /// Provides methods for allowing quantization of images pixels with configurable dithering. 9 | /// 10 | public interface IQuantizer 11 | { 12 | ///// 13 | ///// Gets the error diffusion algorithm to apply to the output image. 14 | ///// 15 | //IErrorDiffuser Diffuser { get; } 16 | 17 | ///// 18 | ///// Creates the generic frame quantizer 19 | ///// 20 | ///// The pixel format. 21 | ///// The 22 | //IFrameQuantizer CreateFrameQuantizer() 23 | // where TPixel : struct, IPixel; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Utils/Endianness.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | /// 8 | /// Endianness of a converter 9 | /// 10 | internal enum Endianness 11 | { 12 | /// 13 | /// Little endian - least significant byte first 14 | /// 15 | LittleEndian, 16 | 17 | /// 18 | /// Big endian - most significant byte first 19 | /// 20 | BigEndian 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Utils/HashHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Formats 6 | { 7 | internal static class HashHelpers 8 | { 9 | public static readonly int RandomSeed = Guid.NewGuid().GetHashCode(); 10 | 11 | public static int Combine(int h1, int h2) 12 | { 13 | unchecked 14 | { 15 | // RyuJIT optimizes this to use the ROL instruction 16 | // Related GitHub pull request: dotnet/coreclr#1830 17 | uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); 18 | return ((int)rol5 + h1) ^ h2; 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/Utils/MathF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.CompilerServices; 4 | using System.Text; 5 | 6 | namespace Geb.Image.Formats 7 | { 8 | public static class MathF 9 | { 10 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 11 | public static float Round(float val) 12 | { 13 | 14 | return (float)Math.Round(val); 15 | } 16 | 17 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 18 | public static float Round(float val, MidpointRounding midpointRounding) 19 | { 20 | return (float)Math.Round(val, midpointRounding); 21 | } 22 | 23 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 24 | public static float Ceiling(float val) 25 | { 26 | 27 | return (float)Math.Ceiling(val); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Geb.Image/Formats/readme.md: -------------------------------------------------------------------------------- 1 | Translate from SixLabors.ImageSharp -------------------------------------------------------------------------------- /src/Geb.Image/Geb.Image.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 5.0.0 6 | 7 | 8 | 9 | true 10 | 11 | 12 | 13 | true 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | True 31 | True 32 | Block8x8F.Generated.tt 33 | 34 | 35 | True 36 | True 37 | GenericBlock8x8.Generated.tt 38 | 39 | 40 | 41 | 42 | 43 | TextTemplatingFileGenerator 44 | Block8x8F.Generated.cs 45 | 46 | 47 | TextTemplatingFileGenerator 48 | GenericBlock8x8.Generated.cs 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/Geb.Image/Geb.Image.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | <_LastSelectedProfileId>D:\Projects\01_Public_Geb.Image\src\Geb.Image\Properties\PublishProfiles\FolderProfile.pubxml 6 | 7 | -------------------------------------------------------------------------------- /src/Geb.Image/IImage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Drawing; 5 | 6 | namespace Geb.Image 7 | { 8 | public interface IImage 9 | { 10 | int Width { get; } 11 | int Height { get; } 12 | int BytesPerPixel { get; } 13 | Bitmap ToBitmap(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Geb.Image/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | FileSystem 8 | Release 9 | netstandard2.0 10 | bin\Release\PublishOutput 11 | 12 | -------------------------------------------------------------------------------- /src/Geb.Image/Properties/PublishProfiles/FolderProfile.pubxml.user: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/FilterKernel.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Geb.Image 10 | { 11 | public class FilterKernel 12 | { 13 | public Int32 Width { get; private set; } 14 | public Int32 Height { get; private set; } 15 | public Int32 Length { get { return Width * Height; } } 16 | 17 | public T[] Data { get; private set; } 18 | public Int32 Scale { get; private set; } 19 | 20 | public FilterKernel(T[] data, Int32 width, Int32 height, Int32 scale) 21 | { 22 | if (data == null) throw new ArgumentNullException("data"); 23 | if (height < 1) throw new ArgumentOutOfRangeException("height"); 24 | if (width < 1) throw new ArgumentOutOfRangeException("width"); 25 | 26 | this.Width = width; 27 | this.Height = height; 28 | this.Scale = scale; 29 | this.Data = data; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Image.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2013 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | * 4 | * 建立时间: 3/8/2013 11:14:37 AM 5 | * 修改记录: 6 | * 7 | ************************************************************************/ 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Runtime.InteropServices; 12 | using System.Text; 13 | 14 | namespace Geb.Image 15 | { 16 | public class Image : IDisposable 17 | where T:struct 18 | { 19 | public unsafe Byte* Data { get; private set; } 20 | 21 | public int ByteLength { get; private set; } 22 | 23 | public unsafe Span DataSpan { get { return new Span((void*)Data, ByteLength); } } 24 | 25 | public unsafe ReadOnlySpan DataSpanReadOnly { get { return new ReadOnlySpan((void*)Data, ByteLength); } } 26 | 27 | public unsafe Image(int width, int height = 1) 28 | { 29 | if (width <= 0) throw new ArgumentOutOfRangeException("width"); 30 | else if (height <= 0) throw new ArgumentOutOfRangeException("height"); 31 | ByteLength = Marshal.SizeOf(typeof(T)) * width * height; 32 | Data = (Byte*)Marshal.AllocHGlobal(ByteLength); 33 | } 34 | 35 | public unsafe void Dispose() 36 | { 37 | if (Data == null) return; 38 | Marshal.FreeHGlobal((IntPtr)Data); 39 | Data = null; 40 | } 41 | 42 | ~Image() 43 | { 44 | Dispose(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageCieLab.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Geb.Image 10 | { 11 | public partial struct CieLab 12 | { 13 | public double L { get; set; } 14 | public double A { get; set; } 15 | public double B { get; set; } 16 | 17 | public double GetDistance(CieLab other) 18 | { 19 | double deltaL = this.L - other.L; 20 | double deltaA = this.A - other.A; 21 | double deltaB = this.B - other.B; 22 | double distance = deltaL * deltaL + deltaA * deltaA + deltaB * deltaB; 23 | return Math.Sqrt(distance); 24 | } 25 | 26 | public double GetDistanceSquare(CieLab other) 27 | { 28 | double deltaL = this.L - other.L; 29 | double deltaA = this.A - other.A; 30 | double deltaB = this.B - other.B; 31 | return deltaL * deltaL + deltaA * deltaA + deltaB * deltaB; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageCieXyz.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Geb.Image 10 | { 11 | public partial struct CieXyz 12 | { 13 | public static readonly CieXyz D65 = new CieXyz { X = 0.9505f, Y = 1.0f, Z = 1.0890f }; 14 | 15 | public float X { get; set; } 16 | public float Y { get; set; } 17 | public float Z { get; set; } 18 | 19 | public CieLab ToCieLab() 20 | { 21 | float l = 116.0f * Transform(Y / D65.Y) - 16; 22 | float a = 500.0f * (Transform(X / D65.X) - Transform(Y / D65.Y)); 23 | float b = 200.0f * (Transform(Y / D65.Y) - Transform(Z / D65.Z)); 24 | return new CieLab { L = l, A = a, B = b }; 25 | } 26 | 27 | private static float Transform(float t) 28 | { 29 | return ((t > 0.008856) ? (float) Math.Pow(t, (1.0f / 3.0f)) : (7.787f * t + 16.0f / 116.0f)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image 6 | { 7 | public static class ImageExtensions 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageFBgr96.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2013 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Runtime.InteropServices; 9 | 10 | namespace Geb.Image 11 | { 12 | public partial struct FBgr96 13 | { 14 | public Single Blue,Red,Green; 15 | 16 | public FBgr96(int red, int green, int blue) 17 | { 18 | Red = red; 19 | Green = green; 20 | Blue = blue; 21 | } 22 | 23 | public FBgr96(byte red, byte green, byte blue) 24 | { 25 | Red = red; 26 | Green = green; 27 | Blue = blue; 28 | } 29 | } 30 | 31 | public partial class ImageFBgr96 : IImage, IDisposable 32 | { 33 | public const int ChannelCount = 3; 34 | 35 | public int BytesPerPixel { get; } = 12; 36 | 37 | #region Image <-> Bitmap 所需的方法 38 | 39 | private unsafe void Copy(Bgr24* from, void* to, int length) 40 | { 41 | throw new NotImplementedException(); 42 | } 43 | 44 | private unsafe void Copy(Bgra32* from, void* to, int length) 45 | { 46 | throw new NotImplementedException(); 47 | } 48 | 49 | private unsafe void Copy(byte* from, void* to, int length) 50 | { 51 | throw new NotImplementedException(); 52 | } 53 | 54 | private PixelFormat GetOutputBitmapPixelFormat() 55 | { 56 | throw new NotImplementedException(); 57 | } 58 | 59 | private unsafe void ToBitmapCore(byte* src, byte* dst, int width) 60 | { 61 | throw new NotImplementedException(); 62 | } 63 | 64 | #endregion 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageFloat.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2012 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Drawing; 9 | 10 | namespace Geb.Image 11 | { 12 | public partial class ImageFloat : IImage, IDisposable 13 | { 14 | public const int ChannelCount = 1; 15 | 16 | public int BytesPerPixel { get; } = 4; 17 | 18 | #region Image <-> Bitmap 所需的方法 19 | 20 | private unsafe void Copy(Bgr24* from, void* to, int length) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | 25 | private unsafe void Copy(Bgra32* from, void* to, int length) 26 | { 27 | throw new NotImplementedException(); 28 | } 29 | 30 | private unsafe void Copy(byte* from, void* to, int length) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | 35 | private unsafe void ToBitmapCore(byte* src, byte* dst, int width) 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | 40 | private PixelFormat GetOutputBitmapPixelFormat() 41 | { 42 | return PixelFormat.Format32bppBgra; 43 | } 44 | 45 | #endregion 46 | 47 | public unsafe ImageU8 ToImageU8(int coeff = 255) 48 | { 49 | ImageU8 img = new ImageU8(this.Width, this.Height); 50 | float* p = this.Start; 51 | float* pEnd = p + this.Length; 52 | byte* dst = img.Start; 53 | float val = 0; 54 | while (p < pEnd) 55 | { 56 | val = *p * coeff; 57 | val = Math.Min(255,Math.Max(val, 0)); 58 | *dst = (Byte)val; 59 | p++; 60 | dst++; 61 | } 62 | return img; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageHsl.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2013 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Text; 9 | 10 | namespace Geb.Image 11 | { 12 | public partial struct Hsl 13 | { 14 | public float H; 15 | public float S; 16 | public float L; 17 | 18 | public Hsl(float h, float s, float l) 19 | { 20 | H = h; 21 | S = s; 22 | L = l; 23 | } 24 | } 25 | 26 | public partial class ImageHsl : IImage, IDisposable 27 | { 28 | public const int ChannelCount = 3; 29 | 30 | public int BytesPerPixel { get; } = 12; 31 | 32 | #region Image <-> Bitmap 所需的方法 33 | 34 | private unsafe void Copy(Bgr24* from, void* to, int length) 35 | { 36 | UnmanagedImageConverter.ToHsl(from, (Hsl*)to, length); 37 | } 38 | 39 | private unsafe void Copy(Bgra32* from, void* to, int length) 40 | { 41 | UnmanagedImageConverter.ToHsl(from, (Hsl*)to, length); 42 | } 43 | 44 | private unsafe void Copy(byte* from, void* to, int length) 45 | { 46 | UnmanagedImageConverter.ToHsl(from, (Hsl*)to, length); 47 | } 48 | 49 | private unsafe void ToBitmapCore(byte* src, byte* dst, int width) 50 | { 51 | UnmanagedImageConverter.ToRgb24((Hsl*)src, (Bgr24*)dst, width); 52 | } 53 | 54 | private PixelFormat GetOutputBitmapPixelFormat() 55 | { 56 | return PixelFormat.Format24bppBgr; 57 | } 58 | 59 | #endregion 60 | 61 | public unsafe ImageHsl(ImageBgr24 img) 62 | : this(img.Width, img.Height) 63 | { 64 | int length = img.Length; 65 | UnmanagedImageConverter.ToLab24(img.Start, (Lab24*)this.Start, length); 66 | } 67 | 68 | public unsafe ImageBgr24 ToImageRgb24() 69 | { 70 | ImageBgr24 img = new ImageBgr24(this.Width, this.Height); 71 | UnmanagedImageConverter.ToBgr24((Lab24*)this.Start, img.Start, img.Length); 72 | return img; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/ImageInt16.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2019 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Drawing; 9 | 10 | namespace Geb.Image 11 | { 12 | public partial class ImageInt16 : IImage, IDisposable 13 | { 14 | public const int ChannelCount = 1; 15 | 16 | public int BytesPerPixel { get; } = 2; 17 | 18 | #region Image <-> Bitmap 所需的方法 19 | 20 | private unsafe void Copy(Bgr24* from, void* to, int length) 21 | { 22 | UnmanagedImageConverter.ToBgra32(from, (Bgra32*)to, length); 23 | } 24 | 25 | private unsafe void Copy(Bgra32* from, void* to, int length) 26 | { 27 | UnmanagedImageConverter.Copy((Byte*)from, (Byte*)to, length * 4); 28 | } 29 | 30 | private unsafe void Copy(byte* from, void* to, int length) 31 | { 32 | if (length < 1) return; 33 | Byte* end = from + length; 34 | Int32* dst = (Int32*)to; 35 | while (from != end) 36 | { 37 | *dst = *from; 38 | from++; 39 | dst++; 40 | } 41 | } 42 | 43 | private PixelFormat GetOutputBitmapPixelFormat() 44 | { 45 | return PixelFormat.Format8bpp; 46 | } 47 | 48 | private unsafe void ToBitmapCore(byte* src, byte* dst, int width) 49 | { 50 | Int32* start = (Int32*)src; 51 | Int32* end = start + width; 52 | while (start != end) 53 | { 54 | Int32 val = *start; 55 | val = val < 0 ? 0 : val > 255 ? 255 : val; 56 | *dst = (byte)val; 57 | start++; 58 | dst++; 59 | } 60 | } 61 | 62 | #endregion 63 | 64 | } 65 | } -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageBgr24.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = Bgr24; 15 | using TChannel = System.Byte; 16 | using TCache = System.Int32; 17 | using TKernel = System.Int32; 18 | using TImage = Geb.Image.ImageBgr24; 19 | 20 | public static partial class ImageBgr24ClassHelper 21 | { 22 | #region include "__ImageClassHelper_Template.cs" 23 | #endregion 24 | } 25 | 26 | public partial class ImageBgr24 27 | { 28 | #region include "__Image_Template.cs" [Image_Template -> ImageBgr24] 29 | #endregion 30 | } 31 | 32 | public partial struct Bgr24 33 | { 34 | #region include "__Pixel_Template.cs" 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageBgra32.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = Bgra32; 15 | using TChannel = System.Byte; 16 | using TCache = System.Int32; 17 | using TKernel = System.Int32; 18 | using TImage = Geb.Image.ImageBgra32; 19 | 20 | public static partial class ImageBgra32ClassHelper 21 | { 22 | #region include "__ImageClassHelper_Template.cs" 23 | #endregion 24 | } 25 | 26 | public partial class ImageBgra32 27 | { 28 | #region include "__Image_Template.cs" [Image_Template -> ImageBgra32] 29 | #endregion 30 | 31 | #region include "__Paramid_Templete.cs" 32 | #endregion 33 | } 34 | 35 | public partial struct Bgra32 36 | { 37 | #region include "__Pixel_Template.cs" 38 | #endregion 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageFBgr96.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2013 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = FBgr96; 15 | using TChannel = System.Single; 16 | using TCache = System.Single; 17 | using TKernel = System.Single; 18 | using TImage = Geb.Image.ImageFBgr96; 19 | 20 | public static partial class ImageFBgr96ClassHelper 21 | { 22 | #region include "__ImageClassHelper_Template.cs" 23 | #endregion 24 | } 25 | 26 | public partial class ImageFBgr96 27 | { 28 | #region include "__Image_Template.cs" [Image_Template -> ImageFBgr96] 29 | #endregion 30 | } 31 | 32 | public partial struct FBgr96 33 | { 34 | #region include "__Pixel_Template.cs" 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageFloat.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2012 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = System.Single; 15 | using TChannel = System.Single; 16 | using TChannelTemp = System.Single; 17 | using TCache = System.Single; 18 | using TKernel = System.Single; 19 | using TImage = Geb.Image.ImageFloat; 20 | 21 | public static partial class ImageFloatClassHelper 22 | { 23 | #region include "__ImageClassHelper_Template.cs" 24 | #endregion 25 | } 26 | 27 | public partial class ImageFloat 28 | { 29 | #region include "__Image_Template.cs" [Image_Template -> ImageFloat] 30 | #endregion 31 | 32 | #region include "__ImageFilter_Template.cs" 33 | #endregion 34 | } 35 | } 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageGrad.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = Grad; 15 | using TChannel = System.Single; 16 | using TImage = Geb.Image.ImageGrad; 17 | 18 | public static partial class ImageGradClassHelper 19 | { 20 | #region include "__ImageClassHelper_Template.cs" 21 | #endregion 22 | } 23 | 24 | public partial class ImageGrad 25 | { 26 | #region include "__Image_Template.cs" [Image_Template -> ImageGrad] 27 | #endregion 28 | } 29 | 30 | public partial struct Grad 31 | { 32 | #region include "__Pixel_Template.cs" 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageGradXY.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2015 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = GradXY; 15 | using TChannel = System.Int16; 16 | using TImage = Geb.Image.ImageGradXY; 17 | 18 | public static partial class ImageGradXYClassHelper 19 | { 20 | #region include "__ImageClassHelper_Template.cs" 21 | #endregion 22 | } 23 | 24 | public partial class ImageGradXY 25 | { 26 | #region include "__Image_Template.cs" [Image_Template -> ImageGradXY] 27 | #endregion 28 | } 29 | 30 | public partial struct GradXY 31 | { 32 | #region include "__Pixel_Template.cs" 33 | #endregion 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageHsl.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2013 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Drawing; 9 | using System.Drawing.Imaging; 10 | using System.Runtime.CompilerServices; 11 | using System.Runtime.InteropServices; 12 | 13 | namespace Geb.Image 14 | { 15 | using TPixel = Geb.Image.Hsl; 16 | using TChannel = System.Single; 17 | using TCache = Geb.Image.Hsl; 18 | using TKernel = System.Single; 19 | using TImage = Geb.Image.ImageHsl; 20 | 21 | public partial struct Hsl 22 | { 23 | #region include "__Pixel_Template.cs" 24 | #endregion 25 | } 26 | 27 | public static partial class ImageHslClassHelper 28 | { 29 | #region include "__ImageClassHelper_Template.cs" 30 | #endregion 31 | } 32 | 33 | public partial class ImageHsl 34 | { 35 | #region include "__Image_Template.cs" [Image_Template -> ImageHsl] 36 | #endregion 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageInt16.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = System.Int16; 15 | using TChannel = System.Int16; 16 | using TChannelTemp = System.Int16; 17 | using TCache = System.Int32; 18 | using TKernel = System.Int16; 19 | using TImage = Geb.Image.ImageInt16; 20 | 21 | public static partial class ImageInt16ClassHelper 22 | { 23 | #region include "__ImageClassHelper_Template.cs" 24 | #endregion 25 | } 26 | 27 | public partial class ImageInt16 28 | { 29 | #region include "__Image_Template.cs" [Image_Template -> ImageInt16] 30 | #endregion 31 | 32 | #region include "__ImageFilter_Template.cs" 33 | #endregion 34 | } 35 | } 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageInt32.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = System.Int32; 15 | using TChannel = System.Int32; 16 | using TChannelTemp = System.Int32; 17 | using TCache = System.Int32; 18 | using TKernel = System.Int32; 19 | using TImage = Geb.Image.ImageInt32; 20 | 21 | public static partial class ImageInt32ClassHelper 22 | { 23 | #region include "__ImageClassHelper_Template.cs" 24 | #endregion 25 | } 26 | 27 | public partial class ImageInt32 28 | { 29 | #region include "__Image_Template.cs" [Image_Template -> ImageInt32] 30 | #endregion 31 | 32 | #region include "__ImageFilter_Template.cs" 33 | #endregion 34 | } 35 | } 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageLab24.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = Geb.Image.Lab24; 15 | using TChannel = System.Byte; 16 | using TCache = Geb.Image.Lab24; 17 | using TKernel = System.Int32; 18 | using TImage = Geb.Image.ImageLab24; 19 | 20 | public partial struct Lab24 21 | { 22 | #region include "__Pixel_Template.cs" 23 | #endregion 24 | } 25 | 26 | public static partial class ImageLab24ClassHelper 27 | { 28 | #region include "__ImageClassHelper_Template.cs" 29 | #endregion 30 | } 31 | 32 | public partial class ImageLab24 33 | { 34 | #region include "__Image_Template.cs" [Image_Template -> ImageLab24] 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageRgbS.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = RgbS; 15 | using TCache = System.Single; 16 | using TKernel = System.Single; 17 | using TImage = Geb.Image.ImageRgbS; 18 | using TChannel = System.Single; 19 | 20 | public static partial class ImageRgbSClassHelper 21 | { 22 | #region include "__ImageClassHelper_Template.cs" 23 | #endregion 24 | } 25 | 26 | public partial class ImageRgbS 27 | { 28 | #region include "__Image_Template.cs" [Image_Template -> ImageRgbS] 29 | #endregion 30 | } 31 | 32 | public partial struct RgbS 33 | { 34 | #region include "__Pixel_Template.cs" 35 | #endregion 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageSBgra64.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = SBgra64; 15 | using TCache = System.Int32; 16 | using TKernel = System.Int32; 17 | using TImage = Geb.Image.ImageSBgra64; 18 | using TChannel = System.Int16; 19 | 20 | public static partial class ImageSBgra64ClassHelper 21 | { 22 | #region include "__ImageClassHelper_Template.cs" 23 | #endregion 24 | } 25 | 26 | public partial class ImageSBgra64 27 | { 28 | #region include "__Image_Template.cs" [Image_Template -> ImageSBgra64] 29 | #endregion 30 | 31 | #region include "__Paramid_Templete.cs" 32 | #endregion 33 | } 34 | 35 | public partial struct SBgra64 36 | { 37 | #region include "__Pixel_Template.cs" 38 | #endregion 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/_ImageU8.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Drawing; 8 | using System.Drawing.Imaging; 9 | using System.Runtime.CompilerServices; 10 | using System.Runtime.InteropServices; 11 | 12 | namespace Geb.Image 13 | { 14 | using TPixel = System.Byte; 15 | using TChannel = System.Byte; 16 | using TCache = System.Int32; 17 | using TKernel = System.Int32; 18 | using TImage = Geb.Image.ImageU8; 19 | 20 | public static partial class ImageU8ClassHelper 21 | { 22 | #region include "__ImageClassHelper_Template.cs" 23 | #endregion 24 | } 25 | 26 | public partial class ImageU8 27 | { 28 | #region include "__Image_Template.cs" [Image_Template -> ImageU8] 29 | #endregion 30 | 31 | #region include "__ImageFilter_Template.cs" 32 | #endregion 33 | } 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Templates/__Pixel_Template.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using TPixel = System.Byte; 6 | using System; 7 | 8 | namespace Geb.Image.Hidden 9 | { 10 | public struct TPixel_Template 11 | { 12 | /* 13 | #region mixin 14 | 15 | public static Boolean operator ==(TPixel lhs, int rhs) 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | 20 | public static Boolean operator !=(TPixel lhs, int rhs) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | 25 | public static Boolean operator ==(TPixel lhs, double rhs) 26 | { 27 | throw new NotImplementedException(); 28 | } 29 | 30 | public static Boolean operator !=(TPixel lhs, double rhs) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | 35 | public static Boolean operator ==(TPixel lhs, float rhs) 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | 40 | public static Boolean operator !=(TPixel lhs, float rhs) 41 | { 42 | throw new NotImplementedException(); 43 | } 44 | 45 | public static Boolean operator ==(TPixel lhs, TPixel rhs) 46 | { 47 | return lhs.Equals(rhs); 48 | } 49 | 50 | public static Boolean operator !=(TPixel lhs, TPixel rhs) 51 | { 52 | return !lhs.Equals(rhs); 53 | } 54 | 55 | #endregion 56 | */ 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Utils/ImageReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | 6 | namespace Geb.Image 7 | { 8 | using Geb.Image.Formats.Jpeg; 9 | using Geb.Image.Formats.Png; 10 | using Geb.Image.Formats.Bmp; 11 | using Geb.Image.Formats; 12 | 13 | public class UnsupportedImageFormatException: Exception 14 | { 15 | public UnsupportedImageFormatException(String fileName):base("File's Image Format Unsupported: " + fileName) 16 | { 17 | } 18 | } 19 | 20 | public class ImageReader 21 | { 22 | public static ImageReader Instance = new ImageReader(); 23 | 24 | private JpegDecoder jpegDecoder = new JpegDecoder(); 25 | private PngDecoder pngDecoder = new PngDecoder(); 26 | private List formatDetectors; 27 | private ImageReader() { 28 | formatDetectors = new List(); 29 | formatDetectors.Add(new JpegImageFormatDetector()); 30 | formatDetectors.Add(new PngImageFormatDetector()); 31 | } 32 | 33 | private IImageFormat DetectFormat(Stream stream) 34 | { 35 | stream.Position = 0; 36 | int headerLength = (int)Math.Min(stream.Length, 1024); 37 | Byte[] buff = new byte[headerLength]; 38 | stream.Read(buff, 0, headerLength); 39 | stream.Position = 0; 40 | ReadOnlySpan span = new ReadOnlySpan(buff); 41 | foreach(var item in formatDetectors) 42 | { 43 | IImageFormat fmt = item.DetectFormat(buff); 44 | if (fmt != null) return fmt; 45 | } 46 | return null; 47 | } 48 | 49 | public ImageBgra32 Read(String imgFilePath) 50 | { 51 | using(Stream stream = new FileStream(imgFilePath, FileMode.Open)) 52 | { 53 | IImageFormat fmt = DetectFormat(stream); 54 | if (fmt is JpegFormat) 55 | return jpegDecoder.Decode(stream); 56 | else if (fmt is PngFormat) 57 | return pngDecoder.Decode(stream); 58 | } 59 | 60 | throw new UnsupportedImageFormatException(imgFilePath); 61 | 62 | return null; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Geb.Image/UnmanagedImage/Utils/PixelHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image 6 | { 7 | public static class PixelHelper 8 | { 9 | /// 10 | /// 反色 11 | /// 12 | /// 13 | /// 14 | public static Byte Invert(this Byte p) 15 | { 16 | return (byte)(255 - p); 17 | } 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Geb.Image/Utils/Interpolate.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (c) 2010 Hu Fei(xiaotie@geblab.com; geblab, www.geblab.com) 3 | ************************************************************************/ 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Geb.Image 10 | { 11 | public enum InterpolationMode 12 | { 13 | NearestNeighbor = 1, 14 | Bilinear = 2 15 | } 16 | 17 | /// 18 | /// 插值的工具类 19 | /// 20 | public sealed class Interpolate 21 | { 22 | public static Byte LinearInterpolate(Byte v00, Byte v10, Byte v01, Byte v11, double a, double b) 23 | { 24 | int val = (int)Math.Round((1 - a) * (1 - b) * v00 + a * (1 - b) * v10 + b * (1 - a) * v01 + a * b * v11); 25 | if (val < 0) return 0; 26 | else if (val > 255) return 255; 27 | else return (Byte)val; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Geb.Image/Utils/ProjectionTransform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Geb.Image.Utils 6 | { 7 | /// 8 | /// 射影变换 9 | /// 10 | public class ProjectionTransform 11 | { 12 | public double X00, X01, X10, X11; 13 | public double Y00, Y01, Y10, Y11; 14 | public double XX00, XX01, XX10, XX11; 15 | public double YY00, YY01, YY10, YY11; 16 | 17 | public ProjectionTransform( 18 | double x00, double y00, double x01, double y01, double x10, double y10, double x11, double y11, 19 | double xx00, double yy00, double xx01, double yy01, double xx10, double yy10, double xx11, double yy11) 20 | { 21 | this.X00 = x00; 22 | this.X01 = x01; 23 | this.X10 = x10; 24 | this.X11 = x11; 25 | this.Y00 = y00; 26 | this.Y01 = y01; 27 | this.Y10 = y10; 28 | this.Y11 = y11; 29 | this.XX00 = xx00; 30 | this.XX01 = xx01; 31 | this.XX10 = xx10; 32 | this.XX11 = xx11; 33 | this.YY00 = yy00; 34 | this.YY01 = yy01; 35 | this.YY10 = yy10; 36 | this.YY11 = yy11; 37 | } 38 | } 39 | } 40 | --------------------------------------------------------------------------------