internal static unsafe void ExtractMetadata(byte[] data, MetadataType type, byte[] outData, uint outSize) { fixed(byte *ptr = data, outPtr = outData) { if (IntPtr.Size == 8) { WebP_64.ExtractMetadata(ptr, new UIntPtr((ulong)data.Length), outPtr, outSize, type); } else { WebP_32.ExtractMetadata(ptr, new UIntPtr((ulong)data.Length), outPtr, outSize, type); } } }
/// <summary> /// Gets the dimension of the WebP image. /// </summary> /// <param name="data">The input image data.</param> /// <param name="width">The output width of the image.</param> /// <param name="height">The output height of the image.</param> /// <returns>true on success, otherwise false.</returns> internal static unsafe bool WebPGetDimensions(byte[] data, out int width, out int height) { fixed(byte *ptr = data) { if (IntPtr.Size == 8) { return(WebP_64.WebPGetDimensions(ptr, new UIntPtr((ulong)data.Length), out width, out height)); } else { return(WebP_32.WebPGetDimensions(ptr, new UIntPtr((ulong)data.Length), out width, out height)); } } }
internal static unsafe uint GetMetadataSize(byte[] data, MetadataType type) { uint metadataSize; fixed(byte *ptr = data) { if (IntPtr.Size == 8) { metadataSize = WebP_64.GetMetadataSize(ptr, new UIntPtr((ulong)data.Length), type); } else { metadataSize = WebP_32.GetMetadataSize(ptr, new UIntPtr((ulong)data.Length), type); } } return(metadataSize); }
/// <summary> /// The WebP load function. /// </summary> /// <param name="webpBytes">The input image data</param> /// <exception cref="OutOfMemoryException">Insufficient memory to load the WebP image.</exception> /// <exception cref="WebPException"> /// The WebP image is invalid. /// -or- /// A native API parameter is invalid. /// </exception> internal static unsafe void WebPLoad(byte[] webpBytes, System.Drawing.Imaging.BitmapData output) { VP8StatusCode status; fixed(byte *ptr = webpBytes) { int stride = output.Stride; ulong outputSize = (ulong)stride * (ulong)output.Height; if (IntPtr.Size == 8) { status = WebP_64.WebPLoad(ptr, new UIntPtr((ulong)webpBytes.Length), (byte *)output.Scan0, new UIntPtr(outputSize), stride); } else { status = WebP_32.WebPLoad(ptr, new UIntPtr((ulong)webpBytes.Length), (byte *)output.Scan0, new UIntPtr(outputSize), stride); } } if (status != VP8StatusCode.Ok) { switch (status) { case VP8StatusCode.OutOfMemory: throw new OutOfMemoryException(); case VP8StatusCode.InvalidParam: throw new WebPException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidParameterFormat, nameof(WebPLoad))); case VP8StatusCode.UnsupportedFeature: throw new WebPException(Resources.UnsupportedWebPFeature); case VP8StatusCode.BitStreamError: case VP8StatusCode.NotEnoughData: default: throw new WebPException(Resources.InvalidWebPImage); } } }
/// <summary> /// Gets the WebP image information. /// </summary> /// <param name="data">The input image data.</param> /// <param name="info">The output image information.</param> /// <exception cref="OutOfMemoryException">Insufficient memory to load the WebP image.</exception> /// <exception cref="WebPException"> /// The WebP image is invalid. /// -or- /// A native API parameter is invalid. /// </exception> internal static unsafe void WebPGetImageInfo(byte[] data, out ImageInfo info) { VP8StatusCode status; fixed(byte *ptr = data) { if (IntPtr.Size == 8) { status = WebP_64.WebPGetImageInfo(ptr, new UIntPtr((ulong)data.Length), out info); } else { status = WebP_32.WebPGetImageInfo(ptr, new UIntPtr((ulong)data.Length), out info); } } if (status != VP8StatusCode.Ok) { switch (status) { case VP8StatusCode.OutOfMemory: throw new OutOfMemoryException(); case VP8StatusCode.InvalidParam: throw new WebPException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidParameterFormat, nameof(WebPGetImageInfo))); case VP8StatusCode.UnsupportedFeature: throw new WebPException(Resources.UnsupportedWebPFeature); case VP8StatusCode.BitStreamError: case VP8StatusCode.NotEnoughData: default: throw new WebPException(Resources.InvalidWebPImage); } } }
/// <summary> /// The WebP save function. /// </summary> /// <param name="writeImageCallback">The callback used to write the WebP image.</param> /// <param name="input">The input surface.</param> /// <param name="parameters">The encode parameters.</param> /// <param name="metadata">The image metadata.</param> /// <param name="callback">The progress callback.</param> /// <exception cref="ArgumentNullException"><paramref name="writeImageCallback"/> is null. /// or /// <paramref name="input"/> is null.</exception> /// <exception cref="OutOfMemoryException">Insufficient memory to save the image.</exception> /// <exception cref="WebPException">The encoder returned a non-memory related error.</exception> internal static void WebPSave( Surface input, Stream output, EncodeParams parameters, MetadataParams metadata, WebPReportProgress callback) { if (input == null) { throw new ArgumentNullException(nameof(input)); } StreamIOHandler handler = new StreamIOHandler(output); WebPWriteImage writeImageCallback = handler.WriteImageCallback; WebPEncodingError retVal = WebPEncodingError.Ok; if (IntPtr.Size == 8) { retVal = WebP_64.WebPSave(writeImageCallback, input.Scan0.Pointer, input.Width, input.Height, input.Stride, parameters, metadata, callback); } else { retVal = WebP_32.WebPSave(writeImageCallback, input.Scan0.Pointer, input.Width, input.Height, input.Stride, parameters, metadata, callback); } GC.KeepAlive(writeImageCallback); if (retVal != WebPEncodingError.Ok) { switch (retVal) { case WebPEncodingError.OutOfMemory: case WebPEncodingError.BitStreamOutOfMemory: throw new OutOfMemoryException(Resources.InsufficientMemoryOnSave); case WebPEncodingError.FileTooBig: throw new WebPException(Resources.EncoderFileTooBig); case WebPEncodingError.ApiVersionMismatch: throw new WebPException(Resources.ApiVersionMismatch); case WebPEncodingError.MetadataEncoding: throw new WebPException(Resources.EncoderMetadataError); case WebPEncodingError.UserAbort: throw new OperationCanceledException(); case WebPEncodingError.BadDimension: throw new WebPException(Resources.InvalidImageDimensions); case WebPEncodingError.NullParameter: throw new WebPException(Resources.EncoderNullParameter); case WebPEncodingError.InvalidConfiguration: throw new WebPException(Resources.EncoderInvalidConfiguration); case WebPEncodingError.PartitionZeroOverflow: throw new WebPException(Resources.EncoderPartitionZeroOverflow); case WebPEncodingError.PartitionOverflow: throw new WebPException(Resources.EncoderPartitionOverflow); case WebPEncodingError.BadWrite: if (handler.WriteException != null) { throw new IOException(Resources.EncoderBadWrite, handler.WriteException); } else { throw new IOException(Resources.EncoderBadWrite); } default: throw new WebPException(Resources.EncoderGenericError); } } }