IERG2080 Spring 2024
Project Due: 17 May 2024
Rules:
-
This project takes 10% of the course total.
-
Your code will be compiled and tested in theVM. 0 score if the code cannot be
compiled in the VM.
-
No late submission is allowed.
-
This is a group project. Only one member submitting the work to Blackboard is
required.
In this project, you are going to write a simple 2D bitmap editor. You will use a library called ncurses that provides API for direct keyboard inputs, absolute screen coordinates for full-screen outputs, etc.
To compile the demo that illustrates how to use ncurses, you need to install the library first. In your VM, run
sudo apt install libncurses-dev
After installation, you can now compile the example code by
gcc curses_demo.c -o curses_demo -lcurses
The flag -lcurses asks the linker to link with the library named curses. Try to understand the demo code and see how to initialize an ncurses program, how to move a cursor, how to read the pressed key, etc.
Next, you need to understand the portable bitmap format (PBM). The following is an example from Wikipedia https://en.wikipedia.org/wiki/Netpbm#PBM_example
P1
# This is an example bitmap of the letter "J"
6 10
000010
000010
000010
000010
000010
000010
100010
011100
000000
000000
The first line P1 indicates that the file is a portable bitmap, where each pixel is either 0 or 1 (white or black). The line starts with # is a comment that will be ignored by image readers. The line 6 10 indicates the size of the image: 6x10 pixels. After that, the binary digits are the pixel values of the image. Note that the spaces and newlines in the description of the image body can be omitted. Say, the following example gives the same image as the above one.
To open a pbm file, you need an image editor. In Ubuntu, you can use gimp (GNU Image Manipulation Program). Install gimp by
sudo apt install gimp
Suppose your program is named proj. The following is the usage of your program.
./proj [in=in_file] [out=out_file]
./proj [out=out_file] [in=in_file]
Both arguments are optional. Yet, the phase in= or out= must be provided if the
corresponding argument is used. in_file is the input file name, and out_file is the output
file name.
Your program provides an interface for a user to draw a 2D bitmap image. Here are the descriptions. Each item takes 1 point (full score 10 points).
-
If in_file is supplied, load the file. If the file is not a 80x24 PBM, print an error message and terminate the program.
-
Initialize curses. Change the terminal size to 80x24 (width 80, height 24). Turns on REVERSE video mode attribute (black characters on a white background).
-
If in_file is not supplied, fill the whole screen with spaces to show a full reverse background. Otherwise, show the image on the screen. Use # for 1 and a space for 0. For both cases, move the cursor to the top-left corner after the initialization is done.
-
Let the user move the cursor around using the arrow keys (cannot move beyond the boundary of the screen).
-
When the user presses the spacebar, draw or erase a # at the location of the cursor.
-
When the user presses ESC, ends the curses environment and recovers the original
terminal settings.
-
If out_file is not supplied, print the image drawn by the user as a PBM format on the
screen using printf. As the terminal size was 80x24, the image size is 80x24. (The
user can copy the printed content to a .pbm file on their own.)
-
If out_file is supplied, save the PBM data to the file. Print an error message if the file
cannot be saved.
-
Create a Makefile so that you can compile your code by make.
-
Make sure that both orders of arguments work as expected.
Write your code in a single .c file. Compress the .c file with the Makefile into a .zip file, and then submit it to Blackboard.
P1
# This is an example bitmap of the letter "J"
6 10
000010000010000010000010000010000010100010011100000000000000