X Lossless Decoder



-->

  1. X Lossless Decoder Linux
  2. X Lossless Decoder Mac

XLD (Stands for X Lossless Decoder) is a one-stop solution to decode, convert and play various lossless audio files. It also works as a secure CD Ripper, but only for XLD version 20080812 and later. The main feature of this tool is capable of splitting audio into tracks with cue sheet. Jan 19, 2020 NNCP: Lossless Data Compression with Neural Networks. A tiny and obfuscated image decoder using algorithms inspirated from AV1. LibBF is small library to handle arbitrary precision floating point numbers. The TinyPI example computes billions of digits of PI. Run X Window or Windows 2000 in your browser.

After a SkiaSharp application has created or modified a bitmap, the application might want to save the bitmap to the user's photo library:

This task encompasses two steps:

  • Converting the SkiaSharp bitmap to data in a particular file format, such as JPEG or PNG.
  • Saving the result to the photo library using platform-specific code.

File formats and codecs

Most of today's popular bitmap file formats use compression to reduce storage space. The two broad categories of compression techniques are called lossy and lossless. These terms indicate whether or not the compression algorithm results in the loss of data.

The most popular lossy format was developed by the Joint Photographic Experts Group and is called JPEG. The JPEG compression algorithm analyzes the image using a mathematical tool called the discrete cosine transform, and attempts to remove data that is not crucial to preserving the image's visual fidelity. The degree of compression can be controlled with a setting generally referred to as quality. Higher quality settings result in larger files.

In contrast, a lossless compression algorithm analyzes the image for repetition and patterns of pixels that can be encoded in a way that reduces the data but does not result in the loss of any information. The original bitmap data can be restored entirely from the compressed file. The primary lossless compressed file format in use today is Portable Network Graphics (PNG).

Generally, JPEG is used for photographs, while PNG is used for images that have been manually or algorithmically generated. Any lossless compression algorithm that reduces the size of some files must necessarily increase the size of others. Fortunately, this increase in size generally only occurs for data that contains a lot of random (or seemingly random) information.

The compression algorithms are complex enough to warrant two terms that describe the compression and decompression processes:

  • decode — read a bitmap file format and decompress it
  • encode — compress the bitmap and write to a bitmap file format

The SKBitmap class contains several methods named Decode that create an SKBitmap from a compressed source. All that's required is to supply a filename, stream, or array of bytes. The decoder can determine the file format and hand it off to the proper internal decoding function.

In addition, the SKCodec class has two methods named Create that can create an SKCodec object from a compressed source and allow an application to get more involved in the decoding process. (The SKCodec class is shown in the article Animating SkiaSharp Bitmaps in connection with decoding an animated GIF file.)

When encoding a bitmap, more information is required: The encoder must know the particular file format the application wants to use (JPEG or PNG or something else). If a lossy format is desired, the encode must also know the desired level of quality.

The SKBitmap class defines one Encode method with the following syntax:

This method is described in more detail shortly. The encoded bitmap is written to a writable stream. (The 'W' in SKWStream stands for 'writable'.) The second and third arguments specify the file format and (for lossy formats) the desired quality ranging from 0 to 100.

In addition, the SKImage and SKPixmap classes also define Encode methods that are somewhat more versatile, and which you might prefer. You can easily create an SKImage object from an SKBitmap object using the static SKImage.FromBitmap method. You can obtain an SKPixmap object from an SKBitmap object using the PeekPixels method.

One of the Encode methods defined by SKImage has no parameters and automatically saves to a PNG format. That parameterless method is very easy to use.

Platform-specific code for saving bitmap files

When you encode an SKBitmap object into a particular file format, generally you'll be left with a stream object of some sort, or an array of data. Some of the Encode methods (including the one with no parameters defined by SKImage) return an SKData object, which can be converted to an array of bytes using the ToArray method. This data must then be saved to a file.

Saving to a file in application local storage is quite easy because you can use standard System.IO classes and methods for this task. This technique is demonstrated in the article Animating SkiaSharp Bitmaps in connection with animating a series of bitmaps of the Mandelbrot set.

If you want the file to be shared by other applications, it must be saved to the user's photo library. This task requires platform-specific code and the use of the Xamarin.Forms DependencyService.

The SkiaSharpFormsDemo project in the SkiaSharpFormsDemos application defines an IPhotoLibrary interface used with the DependencyService class. This defines the syntax of a SavePhotoAsync method:

This interface also defines the PickPhotoAsync method, which is used to open the platform-specific file-picker for the device's photo library.

Lossless

For SavePhotoAsync, the first argument is an array of bytes that contains the bitmap already encoded into a particular file format, such as JPEG or PNG. It's possible that an application might want to isolate all the bitmaps it creates into a particular folder, which is specified in the next parameter, followed by the file name. The method returns a Boolean indicating success or not.

The following sections discuss how SavePhotoAsync is implemented on each platform.

The iOS implementation

The iOS implementation of SavePhotoAsync uses the SaveToPhotosAlbum method of UIImage:

Unfortunately, there is no way to specify a file name or folder for the image.

The Info.plist file in the iOS project requires a key indicating that it adds images to the photo library:

Watch out! The permission key for simply accessing the photo library is very similar but not the same:

The Android implementation

The Android implementation of SavePhotoAsync first checks if the folder argument is null or an empty string. If so, then the bitmap is saved in the root directory of the photo library. Otherwise, the folder is obtained, and if it doesn't exist, it is created:

The call to MediaScannerConnection.ScanFile isn't strictly required, but if you're testing your program by immediately checking the photo library, it helps a lot by updating the library gallery view.

The AndroidManifest.xml file requires the following permission tag:

The UWP implementation

The UWP implementation of SavePhotoAsync is very similar in structure to the Android implementation:

The Capabilities section of the Package.appxmanifest file requires Pictures Library.

Exploring the image formats

Here's the Encode method of SKImage again:

SKEncodedImageFormat is an enumeration with members that refer to eleven bitmap file formats, some of which are rather obscure:

  • Astc — Adaptive Scalable Texture Compression
  • Bmp — Windows Bitmap
  • Dng — Adobe Digital Negative
  • Gif — Graphics Interchange Format
  • Ico — Windows icon images
  • Jpeg — Joint Photographic Experts Group
  • Ktx — Khronos texture format for OpenGL
  • Pkm — Pokémon save file
  • Png — Portable Network Graphics
  • Wbmp — Wireless Application Protocol Bitmap Format (1 bit per pixel)
  • Webp — Google WebP format

As you'll see shortly, only three of these file formats (Jpeg, Png, and Webp) are actually supported by SkiaSharp.

To save an SKBitmap object named bitmap to the user's photo library, you also need a member of the SKEncodedImageFormat enumeration named imageFormat and (for lossy formats) an integer quality variable. You can use the following code to save that bitmap to a file with the name filename in the folder folder:

The SKManagedWStream class derives from SKWStream (which stands for 'writable stream'). The Encode method writes the encoded bitmap file into that stream. The comments in that code refer to some error checking you might need to perform.

The Save File Formats page in the SkiaSharpFormsDemos application uses similar code to allow you to experiment with saving a bitmap in the various formats.

The XAML file contains an SKCanvasView that displays a bitmap, while the rest of the page contains everything the application needs to call the Encode method of SKBitmap. It has a Picker for a member of the SKEncodedImageFormat enumeration, a Slider for the quality argument for lossy bitmap formats, two Entry views for a filename and folder name, and a Button for saving the file.

The code-behind file loads a bitmap resource and uses the SKCanvasView to display it. That bitmap never changes. The SelectedIndexChanged handler for the Picker modifies the filename with an extension that is the same as the enumeration member:

The Clicked handler for the Button does all the real work. It obtains two arguments for Encode from the Picker and Slider, and then uses the code shown earlier to create an SKManagedWStream for the Encode method. The two Entry views furnish folder and file names for the SavePhotoAsync method.

X Lossless Decoder Linux

Most of this method is devoted to handling problems or errors. If Encode creates an empty array, it means that the particular file format isn't supported. If SavePhotoAsync returns false, then the file wasn't successfully saved.

Here is the program running:

That screenshot shows the only three formats that are supported on these platforms:

  • JPEG
  • PNG
  • WebP

For all the other formats, the Encode method writes nothing into the stream and the resultant byte array is empty.

The bitmap that the Save File Formats page saves is 600-pixels square. With 4 bytes per pixel, that's a total of 1,440,000 bytes in memory. The following table shows the file size for various combinations of file format and quality:

X Lossless Decoder
FormatQualitySize
PNGN/A492K
JPEG02.95K
5022.1K
100206K
WebP02.71K
5011.9K
100101K

You can experiment with various quality settings and examine the results.

Saving finger-paint art

One common use of a bitmap is in drawing programs, where it functions as something called a shadow bitmap. All the drawing is retained on the bitmap, which is then displayed by the program. The bitmap also comes in handy for saving the drawing.

The Finger Painting in SkiaSharp article demonstrated how to use touch tracking to implement a primitive finger-painting program. The program supported only one color and only one stroke width, but it retained the entire drawing in a collection of SKPath objects.

The Finger Paint with Save page in the SkiaSharpFormsDemos sample also retains the entire drawing in a collection of SKPath objects, but it also renders the drawing on a bitmap, which it can save to your photo library.

Much of this program is similar to the original Finger Paint program. One enhancement is that the XAML file now instantiates buttons labeled Clear and Save:

The code-behind file maintains a field of type SKBitmap named saveBitmap. This bitmap is created or recreated in the PaintSurface handler whenever the size of the display surface changes. If the bitmap needs to be recreated, the contents of the existing bitmap are copied to the new bitmap so that everything is retained no matter how the display surface changes in size:

The drawing done by the PaintSurface handler occurs at the very end, and consists solely of rendering the bitmap.

X Lossless Decoder Mac

The touch processing is similar to the earlier program. The program maintains two collections, inProgressPaths and completedPaths, that contain everything the user has drawn since the last time the display was cleared. For each touch event, the OnTouchEffectAction handler calls UpdateBitmap:

The UpdateBitmap method redraws saveBitmap by creating a new SKCanvas, clearing it, and then rendering all the paths on the bitmap. It concludes by invalidating canvasView so that the bitmap can be drawn on the display.

Here are the handlers for the two buttons. The Clear button clears both path collections, updates saveBitmap (which results in clearing the bitmap), and invalidates the SKCanvasView:

The Save button handler uses the simplified Encode method from SKImage. This method encodes using the PNG format. The SKImage object is created based on saveBitmap, and the SKData object contains the encoded PNG file.

The ToArray method of SKData obtains an array of bytes. This is what is passed to the SavePhotoAsync method, along with a fixed folder name, and a unique filename constructed from the current date and time.

Here's the program in action:

A very similar technique is used in the SpinPaint sample. This is also a finger-painting program except that the user paints on a spinning disk that then reproduces the designs on its other four quadrants. The color of the finger paint changes as the disk is spinning:

The Save button of SpinPaint class is similar to Finger Paint in that it saves the image to a fixed folder name (SpainPaint) and a filename constructed from the date and time.

Related links