Code organization
Your implementation must follow these strict organizational rules:main.c restrictions
All other functions must be in separate.c files in the src/ directory. This restriction exists because of how the Criterion testing framework is used for grading.
File organization
- You may create as many
.cfiles as you need insrc/ - You may create as many header files as you need in
include/ - Do NOT modify files marked “DO NOT MODIFY” at the beginning
- These files will be replaced with original versions during grading
Part 1: Command-line argument processing
Required functionality
Implement a two-pass argument processing system: First pass:- Check for
-hflag (if present, print usage and exit successfully) - Locate and validate the required
-f <filename>flag - Extract the PNG filename
- Process all operation flags in the order they appear
- Execute each operation and produce the specified output
Supported operations
-h (Help)
-h (Help)
Print the usage message to stdout and exit with
EXIT_SUCCESS.Use the PRINT_USAGE() macro from global.h.-f <filename> (Required)
-f <filename> (Required)
Specify the input PNG file. Required for all operations except
-h.If missing or has no filename argument, print error to stderr and exit with EXIT_FAILURE.-s (Chunk summary)
-s (Chunk summary)
Print a summary of all chunks in the PNG file:
-i (IHDR fields)
-i (IHDR fields)
Print the IHDR header fields:Color type descriptions: (Grayscale), (RGB), (Palette), (Grayscale with Alpha), (RGB with Alpha)Interlace descriptions: (None) for 0, (Adam7) for 1
-p (Palette)
-p (Palette)
Print palette summary (only valid for color type 3 images):If no PLTE chunk exists or parsing fails, print error to stderr.
-e <message> -o <outfile> (Encode)
-e <message> -o <outfile> (Encode)
Encode a secret message into the PNG image using LSB steganography.On success, print:On failure (message too long, file errors), print error to stderr and exit with
EXIT_FAILURE.-d (Decode)
-d (Decode)
Extract and print the hidden message:On failure, print error to stderr and exit with
EXIT_FAILURE.-m <file2> -o <outfile> [-w <x>] [-g <y>] (Overlay)
-m <file2> -o <outfile> [-w <x>] [-g <y>] (Overlay)
Overlay a smaller PNG onto the input PNG at coordinates (x, y).On failure, print error to stderr and exit with
-w: X offset (column), defaults to 0 if not specified-g: Y offset (row), defaults to 0 if not specified-wand-gare optional and may appear in any order after-o
EXIT_FAILURE.Output requirements
- Use the provided macros in
global.hfor all output - No extraneous output to stdout in normal operation
- Use the
debug()macro for debugging messages (only shown in debug builds) - Error messages go to stderr, normal output to stdout
Example invocations
Part 2: PNG parsing
Required functions
You must implement these functions in the appropriate source files: png_reader.c:png_open()- Open and validate PNG signaturepng_read_chunk()- Read next chunk with CRC validationpng_free_chunk()- Free chunk memorypng_extract_ihdr()- Extract and parse IHDR chunkpng_extract_plte()- Extract and parse PLTE chunkpng_summary()- Read all chunks into summary array
png_parse_ihdr()- Parse IHDR chunk datapng_parse_plte()- Parse PLTE chunk data
png_crc()- Compute CRC-32 checksum
Data structures
Use the provided structures from the header files:Memory management
- Use
malloc()andcalloc()for dynamic allocation - Always check for allocation failures
- Free all allocated memory when done
- Use
png_free_chunk()to free chunk data - Avoid memory leaks (will be tested with Valgrind)
Endianness
PNG uses big-endian encoding for all multi-byte integers. Your program runs on little-endian x64, so you must convert byte order.
util.c or implement your own conversions.
Part 3: Steganography
LSB encoding
Implementpng_encode_lsb() to hide messages in images:
For non-palette images (color types 0, 2, 4, 6):
- Modify the LSB of the first channel of each pixel
- One bit per pixel (0 or 1)
- Message capacity: width × height bits
- Duplicate palette colors to create identical-color pairs
- Swap between pair indices to encode 0 or 1 bits
- Visually undetectable since colors are identical
LSB decoding
Implementpng_extract_lsb() to extract hidden messages:
- Read bits in the same order they were written
- Reconstruct bytes from 8 bits each
- Stop when null terminator is found
- Support both encoding methods (direct LSB and palette pairs)
Requirements
- Only support 8-bit images (
bit_depth == 8) - Check message fits in image capacity
- Include null terminator in capacity calculation
- Never modify filter bytes at the start of scanlines
- Use PNG-compatible zlib compression for output
Part 4: Image overlay
Implementation
Implementpng_overlay_paste() to composite images:
PNG filters
You must support all 5 PNG filter types during unfiltering:- None - No filtering
- Sub - Difference from left neighbor
- Up - Difference from above neighbor
- Average - Average of left and above
- Paeth - Paeth predictor algorithm
Palette merging
- Add all colors from large image palette
- Add new colors from small image palette (if not already present)
- Maximum 256 total colors
- Create index mapping for small image
- Remap all small image pixel indices before pasting
Testing requirements
Provided tests
Write your own tests
You STRONGLY encouraged to:- Write additional Criterion tests
- Test edge cases and error conditions
- Test with various PNG files from
tests/data/ - Use
hdto examine binary file output - Verify output format exactly matches specifications
Testing with Criterion
Run tests with:Deliverables
You must submit:- All source code (
.cfiles) - Any additional header files you created
- Your code must compile with
makeandmake debug - All tests must run without crashes
Make sure to test compilation with both
make clean all and make clean debug before submission.Next steps
CLI arguments
Start implementing Part 1
PNG format
Learn PNG file structure
API reference
Review function signatures
Grading
Understand how you’ll be graded