Overview of codecs architecture
In This Topic
Definitions:
- Decoder - an object that performs decoding of images of certain format.
- Encoder - an object that performs encoding of images of certain format.
- Codec - an object that manages encoder and decoder for certain image format.
The SDK contains the open architecture of image codecs, which is used for obtaining information, encoding and decoding images of various formats (TIFF, PDF, BMP, etc).
All classes used for image encoding and decoding are located in Vintasoft.Imaging.Codecs namespace.
The following diagram illustrates the logical links among base classes of the codecs architecture:
The basic classes, illustrated on the above diagram, are divided into four levels of abstraction:
- The "codecs" level consists from AvailableCodecs, AvailableDecoders, AvailableEncoders,Codec and derived classes. AvailableCodecs, AvailableDecoders and AvailableEncoders classes provide information about available decoders and encoders as well as provide the ability to add and remove codecs. Codec and derived classes contain methods allowing to create encoder or decoder for specific image formats.
- The "encoder/decoder" level consists from EncoderBase and DecoderBase classes and derived classes,which provide the unified access to the functions intended for obtaining information and image encoding/decoding.
-
The "image file" level consists from ImageFileBase<T> and derived classes and related classes. The classes, which are derived from ImageFileBase<T> and ImagePage classes, provide the full access to all features of image decoding/encoding and to the metadata of specific format.
ImageFileSource class is used by ImageFileBase<T> hierarchy classes for reading/writing binary data from an instance of System.IO.Stream object.
- The "encoded data" level represents System.IO.Stream class, which contains image data encoded ina specific format (TIFF, PDF, BMP, etc).
1. "Codec" and "AvailableCodecs" classes
Static
AvailableCodecs class contains information about available codecs as well as provides the ability to remove and add new codecs:
The
Codec class is base class for all codecs. The
Codec class defines how to create decoder and encoder for images of specific format.
Codec class includes the following informative properties:
New codec, derived from
Codec class, always must implement at least the following methods:
- Codec.CreateDecoder - creates an instance of class derived from DecoderBase class using constructor without parameters or using constructor which receives a stream containing encoded image data.
- Codec.CreateEncoder - creates an instance of class derived from EncoderBase class using constructor without parameters.
Important: The static
Codec.CreateStandardCodec method allows to create by name a "standard" codec for the following image file formats: Bmp, Docx, Emf, Gif, Icon, Jbig2, Jpeg, Jpeg2000, Pbm, Pdf, Png, Raw, Tga, Tiff, Webp, Wmf, Xlsx.
Here is C#/VB.NET code that demonstrates how to obtain information about available codecs and their characteristics:
/// <summary>
/// Shows detailed information about available codecs.
/// </summary>
public static void ShowAvailableCodecsInfo()
{
foreach (Vintasoft.Imaging.Codecs.Codec codec in Vintasoft.Imaging.Codecs.AvailableCodecs.Codecs)
{
string codecInfo = "";
if (codec.CanCreateDecoder && codec.CanCreateEncoder)
codecInfo = "decoder, encoder";
else if (codec.CanCreateDecoder)
codecInfo = "decoder";
else if (codec.CanCreateEncoder)
codecInfo = "encoder";
System.Console.WriteLine(string.Format("{0} codec ({1}):", codec.Name, codecInfo));
System.Console.Write(" File extensions:");
for (int i = 0; i < codec.FileExtensions.Length; i++)
{
System.Console.Write(string.Format(" *{0}", codec.FileExtensions[i].ToLowerInvariant()));
}
System.Console.WriteLine();
}
}
/* This code example produces the following output:
Raw codec (decoder):
File extensions: *.nef *.nrw *.cr2 *.crw *.dng
Tiff codec (decoder, encoder):
File extensions: *.tif *.tiff
Gif codec (decoder, encoder):
File extensions: *.gif
Png codec (decoder, encoder):
File extensions: *.png
Jpeg codec (decoder, encoder):
File extensions: *.jpg *.jpeg
Bmp codec (decoder, encoder):
File extensions: *.bmp
Pdf codec (decoder, encoder):
File extensions: *.pdf
Jbig2 codec (decoder, encoder):
File extensions: *.jb2 *.jbig2
Jpeg2000 codec (decoder, encoder):
File extensions: *.jp2 *.jpc *.j2k *.j2c
Dicom codec (decoder):
File extensions: *.dcm *.dic *.acr
Docx codec (decoder):
File extensions: *.docx
Wmf codec (decoder):
File extensions: *.wmf
Emf codec (decoder):
File extensions: *.emf
Icon codec (decoder):
File extensions: *.ico *.cur
Jpeg-LS codec (decoder):
File extensions: *.jls
Pcx codec (decoder, encoder):
File extensions: *.pcx
*/
''' <summary>
''' Shows detailed information about available codecs.
''' </summary>
Public Shared Sub ShowAvailableCodecsInfo()
For Each codec As Vintasoft.Imaging.Codecs.Codec In Vintasoft.Imaging.Codecs.AvailableCodecs.Codecs
Dim codecInfo As String = ""
If codec.CanCreateDecoder AndAlso codec.CanCreateEncoder Then
codecInfo = "decoder, encoder"
ElseIf codec.CanCreateDecoder Then
codecInfo = "decoder"
ElseIf codec.CanCreateEncoder Then
codecInfo = "encoder"
End If
System.Console.WriteLine(String.Format("{0} codec ({1}):", codec.Name, codecInfo))
System.Console.Write(" File extensions:")
For i As Integer = 0 To codec.FileExtensions.Length - 1
System.Console.Write(String.Format(" *{0}", codec.FileExtensions(i).ToLowerInvariant()))
Next
System.Console.WriteLine()
Next
End Sub
' This code example produces the following output:
'
' Raw codec (decoder):
' File extensions: *.nef *.nrw *.cr2 *.crw *.dng
' Tiff codec (decoder, encoder):
' File extensions: *.tif *.tiff
' Gif codec (decoder, encoder):
' File extensions: *.gif
' Png codec (decoder, encoder):
' File extensions: *.png
' Jpeg codec (decoder, encoder):
' File extensions: *.jpg *.jpeg
' Bmp codec (decoder, encoder):
' File extensions: *.bmp
' Pdf codec (decoder, encoder):
' File extensions: *.pdf
' Jbig2 codec (decoder, encoder):
' File extensions: *.jb2 *.jbig2
' Jpeg2000 codec (decoder, encoder):
' File extensions: *.jp2 *.jpc *.j2k *.j2c
' Dicom codec (decoder):
' File extensions: *.dcm *.dic *.acr
' Docx codec (decoder):
' File extensions: *.docx
' Wmf codec (decoder):
' File extensions: *.wmf
' Emf codec (decoder):
' File extensions: *.emf
' Icon codec (decoder):
' File extensions: *.ico *.cur
' Jpeg-LS codec (decoder):
' File extensions: *.jls
' Pcx codec (decoder, encoder):
' File extensions: *.pcx
'
'
2. "DecoderBase" and "AvailableDecoders" classes
Static
AvailableDecoders class contains information about available decoders and allows to:
VintasoftImage object uses
AvailableDecoders.CreateDecoder method for choosing the decoder, which allows to decode image data from stream or file, which contains image data.
The
DecoderBase class is base class for all decoders. The
DecoderBase class defines the unified set of methods intended for obtaining metadata and image decoding:
Here is C#/VB.NET code that demonstrates how to get the decoder for the specified stream and obtain information about all images encoded in that stream:
/// <summary>
/// Shows detailed information about pages of image stored in specified stream.
/// </summary>
public static void ShowInformationAboutPages(System.IO.Stream stream)
{
Vintasoft.Imaging.Codecs.Decoders.DecoderBase decoder;
try
{
// create appropriate decoder
decoder = Vintasoft.Imaging.Codecs.Decoders.AvailableDecoders.CreateDecoder(stream);
}
catch (Vintasoft.Imaging.Codecs.Decoders.DecoderException ex)
{
System.Console.WriteLine(ex.Message);
return;
}
if (decoder == null)
{
System.Console.WriteLine("Appropriate decoder was not found.");
return;
}
// get the number of pages
System.Console.WriteLine(string.Format("Stream contains {0} page(s).", decoder.PageCount));
for (int i = 0; i < decoder.PageCount; i++)
{
// get the information about the page
Vintasoft.Imaging.Codecs.Decoders.ImageInfo pageImageInfo = decoder.GetImageInfo(i);
System.Console.WriteLine();
// get general image parameters
System.Console.WriteLine(string.Format("Page {0}:", i + 1));
System.Console.WriteLine(string.Format(" Image dimensions: {0}x{1} pixels", pageImageInfo.Width, pageImageInfo.Height));
System.Console.WriteLine(string.Format(" Image resolution: {0}x{1} dpi",
System.Math.Round(pageImageInfo.Resolution.Horizontal), System.Math.Round(pageImageInfo.Resolution.Vertical)));
System.Console.WriteLine(string.Format(" Image bit depth: {0}", pageImageInfo.BitsPerPixel));
System.Console.WriteLine(string.Format(" Image pixel format: {0}", pageImageInfo.PixelFormat));
// get information about palette
int paletteColorCount = pageImageInfo.Palette.ColorCount;
if (paletteColorCount > 0)
System.Console.WriteLine(string.Format(" Image has a palette with {0} colors", paletteColorCount));
else
System.Console.WriteLine(string.Format(" Image has no palette"));
System.Console.WriteLine();
}
}
''' <summary>
''' Shows detailed information about pages of image stored in specified stream.
''' </summary>
Public Shared Sub ShowInformationAboutPages(stream As System.IO.Stream)
Dim decoder As Vintasoft.Imaging.Codecs.Decoders.DecoderBase
Try
' create appropriate decoder
decoder = Vintasoft.Imaging.Codecs.Decoders.AvailableDecoders.CreateDecoder(stream)
Catch ex As Vintasoft.Imaging.Codecs.Decoders.DecoderException
System.Console.WriteLine(ex.Message)
Return
End Try
If decoder Is Nothing Then
System.Console.WriteLine("Appropriate decoder was not found.")
Return
End If
' get the number of pages
System.Console.WriteLine(String.Format("Stream contains {0} page(s).", decoder.PageCount))
For i As Integer = 0 To decoder.PageCount - 1
' get the information about the page
Dim pageImageInfo As Vintasoft.Imaging.Codecs.Decoders.ImageInfo = decoder.GetImageInfo(i)
System.Console.WriteLine()
' get general image parameters
System.Console.WriteLine(String.Format("Page {0}:", i + 1))
System.Console.WriteLine(String.Format(" Image dimensions: {0}x{1} pixels", pageImageInfo.Width, pageImageInfo.Height))
System.Console.WriteLine(String.Format(" Image resolution: {0}x{1} dpi", System.Math.Round(pageImageInfo.Resolution.Horizontal), System.Math.Round(pageImageInfo.Resolution.Vertical)))
System.Console.WriteLine(String.Format(" Image bit depth: {0}", pageImageInfo.BitsPerPixel))
System.Console.WriteLine(String.Format(" Image pixel format: {0}", pageImageInfo.PixelFormat))
' get information about palette
Dim paletteColorCount As Integer = pageImageInfo.Palette.ColorCount
If paletteColorCount > 0 Then
System.Console.WriteLine(String.Format(" Image has a palette with {0} colors", paletteColorCount))
Else
System.Console.WriteLine(String.Format(" Image has no palette"))
End If
System.Console.WriteLine()
Next
End Sub
3. "EncoderBase", "MultipageEncoderBase" and "AvailableEncoders" classes
Static
AvailableEncoders class contains information about available encoders and allows to:
VintasoftImage and
ImageCollection objects use
AvailableEncoders.CreateEncoder method to choose the encoder by name of file to be encoded.
The
EncoderBase class is base class for all encoders. The
EncoderBase class defines unified set of methods intended for image encoding into single-page image format (PNG, BMP, JPEG, JPEG2000):
The
MultipageEncoderBase class is derived from
EncoderBase and defines unified set of methods intended for encoding the image collection into multi-page image format (TIFF, PDF, GIF, JBIG2):
Here is C#/VB.NET code that demonstrates how to choose an encoder for certain file and perform saving of image collection into the file:
/// <summary>
/// Gets an encoder by the filename extension,
/// changes settings of the encoder and
/// saves an image collection to a file using encoder.
/// </summary>
public static void ChangeEncoderSettingsAndSave(Vintasoft.Imaging.ImageCollection images, string filename)
{
// get an encoder by the filename extension
Vintasoft.Imaging.Codecs.Encoders.EncoderBase encoder =
Vintasoft.Imaging.Codecs.Encoders.AvailableEncoders.CreateEncoder(filename);
// if encoder was not found
if (encoder == null)
{
throw new System.Exception("Encoder is not found for specified file extension.");
}
// if encoder is TIFF
if (encoder is Vintasoft.Imaging.Codecs.Encoders.TiffEncoder)
{
// specify that encoded image must be divided into tiles with size 512x512
(encoder as Vintasoft.Imaging.Codecs.Encoders.TiffEncoder).Settings.UseTiles = true;
(encoder as Vintasoft.Imaging.Codecs.Encoders.TiffEncoder).Settings.TileSize = new System.Drawing.Size(512, 512);
}
// create file
using (System.IO.Stream stream = new System.IO.FileStream(filename,
System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
{
// if encoder is multipage
if (encoder is Vintasoft.Imaging.Codecs.Encoders.MultipageEncoderBase)
{
// save all images
(encoder as Vintasoft.Imaging.Codecs.Encoders.MultipageEncoderBase).SaveImages(images, stream);
}
else
{
// check if there is exactly 1 image
if (images.Count != 1)
throw new System.Exception("Single-page encoder cannot be used for saving multiple images.");
encoder.SaveImage(images[0], stream);
}
}
}
''' <summary>
''' Gets an encoder by the filename extension,
''' changes settings of the encoder and
''' saves an image collection to a file using encoder.
''' </summary>
Public Shared Sub ChangeEncoderSettingsAndSave(images As Vintasoft.Imaging.ImageCollection, filename As String)
' get an encoder by the filename extension
Dim encoder As Vintasoft.Imaging.Codecs.Encoders.EncoderBase = Vintasoft.Imaging.Codecs.Encoders.AvailableEncoders.CreateEncoder(filename)
' if encoder was not found
If encoder Is Nothing Then
Throw New System.Exception("Encoder is not found for specified file extension.")
End If
' if encoder is TIFF
If TypeOf encoder Is Vintasoft.Imaging.Codecs.Encoders.TiffEncoder Then
' specify that encoded image must be divided into tiles with size 512x512
TryCast(encoder, Vintasoft.Imaging.Codecs.Encoders.TiffEncoder).Settings.UseTiles = True
TryCast(encoder, Vintasoft.Imaging.Codecs.Encoders.TiffEncoder).Settings.TileSize = New System.Drawing.Size(512, 512)
End If
' create file
Using stream As System.IO.Stream = New System.IO.FileStream(filename, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite)
' if encoder is multipage
If TypeOf encoder Is Vintasoft.Imaging.Codecs.Encoders.MultipageEncoderBase Then
' save all images
TryCast(encoder, Vintasoft.Imaging.Codecs.Encoders.MultipageEncoderBase).SaveImages(images, stream)
Else
' check if there is exactly 1 image
If images.Count <> 1 Then
Throw New System.Exception("Single-page encoder cannot be used for saving multiple images.")
End If
encoder.SaveImage(images(0), stream)
End If
End Using
End Sub
4. Image file hierarchy
ImageFile hierarchy provides a set of classes for parsing, decoding and encoding image files.
The following diagram illustrates the logical links among basic classes of ImageFile architecture:
4.1. Image file
ImageFileBase<T> class is a base class for:
-
abstract SinglePageImageFile<T> class, which is used for creating single-page image files (BmpFile, PngFile, JpegFile, Jpeg2000File, RawImageFile)
-
abstract ImageFile<TPage, TPageCollection> class, which is used for creating multi-page image files (TiffFile, GifFile, Jbig2File, IconFile)
The classes, which are derived from
ImageFileBase<T>, provide access to a collection of file pages (or a page in case of single-page format) and general information about the file. They also implement functions of parsing, saving changes, saving to new source and packing the file.
4.2. Image page
Abstract
ImagePage class defines methods, which allow to obtain information about encoded image (height, width, palette, resolution, etc) and encode image.
Classes
TiffPage,
PngPage,
BmpPage,
DibPage,
GifPage,
IconPage,
JpegPage,
Jpeg2000Page,
Jbig2Page,
RawImagePageBase, which are derived from
ImagePage class, also provides additional information about image: color space, compression, thumbnail and other format specific details.
4.3. Image file block
Each image file consists from file blocks. An abstract
ImageFileBlock class describes a data block in file.
All file blocks have the following common attributes:
- block length
- block offset
- source
Block can be virtual (
ImageFileBlock.IsVirtual, i.e. created in memory without link to the real source (
ImageFileSource). Virtual blocks appear when new file is created or new blocks are added to existing file. Blocks become real after saving the file to the source.
The overriden abstract method
ImageFileBlock.Parse allows to implement the parsing algorithm for the specific block. The overriden abstract method
ImageFileBlock.Write allows to implement the writing of encoded data into the source.
4.4. Image file source
ImageFileSource class allows to read/write data from/to the source. The class implements a wide range of data read/write functions for different data formats: Int16, Uint16, Int32, UInt32, Int64, UInt64, Char, Bool, Single, Double, Byte, Byte[]. The
ImageFileSource class implements read/write operations in little-endian format. The
BigEndianImageSource class implements read/write operations in big-endian format.