Exercise
PCX Width And Height
Objective
Create a program that checks if a file is a PCX image and, if so, displays its width and height using the following specification:
What is the PCX format?
The PCX format is used for storing images. It was created by ZSoft, the company behind the Paintbrush image manipulation program.
Internal details of a PCX file
A PCX file consists of the following parts: a file header, a bitmap header, a color table, and the bytes that define the image. The data forming the file header and the bitmap header are as follows:
Header Position Bytes Meaning
0 1 ID: must be 10
1 1 PCX File Version
0 = Version 2.5
2 = Version 2.8 with Palette
3 = Version 2.8 default palette
4 = Paintbrush for Windows
5 = Version 3.0 or higher, with the end of file palette.
2 1 Must be 1 to indicate RLE
3 1 Bits per pixel
1 - Monochrome
4-16 colors
8 to 256 colors
24-16700000 color (true color, "truecolor")
4 8 Image Coordinates
Xmin, Ymin, Xmax, Ymax (4 data 2 bytes each)
12 2 Horizontal resolution, in dots per inch
14 2 Vertical resolution, in dots per inch
16 48 Color map with the definition of the palette in case of 16 or fewer colors. Organized in fields of 16 bytes * 3.
64 1 Reserved
65 1 Number of planes (4 to 16 colors, 3-bits for RGB -24)
66 2 Bytes per line of image (the image width, measured in bytes)
68 2 Palette information
1 = Color
2 = Grayscale
70 2 Screen width (only used by Paintbrush IV and above)
72 2 Screen height (only used by Paintbrush IV and above)
74 54 bytes of padding, to complete 128 bytes of header. All bytes should be 0.
Using these details, we can find information about the file. For example, to determine the width and height of the image, we should open the file, move to position 4 (counting from 0), and read the four bytes that represent Xmin, Ymin, Xmax, and Ymax. Then we can calculate the width and height as follows: Width = Xmax - Xmin + 1, Height = Ymax - Ymin + 1.
If the version number is 5, the color palette will be in the last 769 bytes of the file. First you will find a value of 12, then the RGB values of the 256 colors in the palette. If these values are displayed on a VGA screen, they should be divided by 4 because the RGB components of a VGA card only go from 0 to 63.
Images in 24-bit color (8 bits, 3 planes) have a palette for each point that stores the components R, G, and B.
Write Your C# Exercise
C# Exercise Example
// Import the necessary namespaces for file handling and basic input/output operations
using System;
using System.IO;
// Declare the main Program class
class Program
{
// Main method where the program starts
static void Main()
{
// Specify the path to the PCX image file
string filePath = "image.pcx"; // Replace this with the path to your PCX file
// Check if the file is a PCX image and display its width and height
try
{
// Open the PCX file using a BinaryReader to read the raw bytes
using (BinaryReader reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
{
// Read the first byte (ID), which must be 10 for a valid PCX file
byte id = reader.ReadByte();
if (id != 10) // Check if the ID is 10, which is required for PCX format
{
Console.WriteLine("This is not a valid PCX file.");
return; // Exit the program if the ID is not correct
}
// Skip the next 3 bytes (Version, Encoding, and Bits per Pixel) since we're not using them here
reader.BaseStream.Seek(3, SeekOrigin.Current);
// Read the coordinates (Xmin, Ymin, Xmax, Ymax) from position 4
reader.BaseStream.Seek(4, SeekOrigin.Begin);
ushort xmin = reader.ReadUInt16(); // Read Xmin (2 bytes)
ushort ymin = reader.ReadUInt16(); // Read Ymin (2 bytes)
ushort xmax = reader.ReadUInt16(); // Read Xmax (2 bytes)
ushort ymax = reader.ReadUInt16(); // Read Ymax (2 bytes)
// Calculate the width and height of the image
int width = xmax - xmin + 1; // Width = Xmax - Xmin + 1
int height = ymax - ymin + 1; // Height = Ymax - Ymin + 1
// Print the width and height of the PCX image
Console.WriteLine($"PCX Image Width: {width} pixels");
Console.WriteLine($"PCX Image Height: {height} pixels");
}
}
catch (Exception ex) // Catch any errors that may occur during file reading
{
// Print the error message to the console
Console.WriteLine($"Error reading the file: {ex.Message}");
}
}
}