Skip to content

Commit

Permalink
Finish program and write documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
whiteeagle44 committed Jun 4, 2021
1 parent 1bf1329 commit f139483
Show file tree
Hide file tree
Showing 9 changed files with 563 additions and 37 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Barcode generator

## About
This program generates a [Code 39](https://en.wikipedia.org/wiki/Code_39) barcode for a given string. In other words, it draws the appropriate sequences of bars and spaces into a bmp file.

Details of the task can be found in `task.pdf` file.

## How to run
This project is precompiled for Linux.
Open terminal in the folder with files.

Type `./program width_of_narrow_bar text_to_be_encoded`

Where:

`width_of_narrow_bar` - 1, 2 or 3

`text_to_be_encoded` - sequence of up to 9 characters (uppercase letters, numbers and [more](https://en.wikipedia.org/wiki/Code_39#/media/File:Free_3_of_9_(Code_39_barcode).svg))

A barcode will be generated in the `output.bmp` file.

## Sample run
```
./program 2 CODE-X86
```

In `output.bmp` file:

![example](documentation/example.bmp)

The correctness of the barcode generated can be verified for example with an Android app:

![example](documentation/screenshot-barcode-scanner.png)

## Implementation
The source for the program is located in `main.c` and `functions.asm` files. It is written in C and 32 bit x86 assembly language. The simplified logic of the core functions in pseudocode is presented in form of diagrams below.
The diagrams were created with the MIPS implementation in mind, but are valid in the x86 case as well.


![Logic chart](documentation/logic.drawio.svg)
Binary file added documentation/example.bmp
Binary file not shown.
422 changes: 422 additions & 0 deletions documentation/logic.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added documentation/screenshot-barcode-scanner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added documentation/task.pdf
Binary file not shown.
72 changes: 70 additions & 2 deletions functions.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ global _put_pixel, put_pixel
global _put_thin_bar, put_thin_bar
global _put_thick_bar, put_thick_bar
global _put_char, put_char
global _encode39, encode39

section .data
;used by put_char
Expand Down Expand Up @@ -39,6 +40,9 @@ section .text
pop edx
%endmacro

; used by encode39
%define STARTING_X 10 ; starting x coordinate of the bar


; int put_pixel(char* pixels, int x, int y);
; sets the color of specified pixel to black
Expand Down Expand Up @@ -153,7 +157,6 @@ put_thick_bar:
; return value: x coordinate of the next character
_put_char:
put_char:

push ebp
mov ebp, esp
push ebx
Expand Down Expand Up @@ -255,4 +258,69 @@ return:
pop esi
pop ebx
pop ebp
ret
ret


; int encode39(char* pixels, int width, char* text);
; encodes text using Code 39 barcode
; arguments:
; DWORD[ebp+8]: char* pixels - address of pixel array
; DWORD[ebp+12]: int width - width in pixels of narrowest bar
; DWORD[ebp+16]: char* text - character to put
; return value: 0 (OK) or -1 (error, character unsupported)
_encode39:
encode39:
push ebp
mov ebp, esp
push ebx

mov edx, STARTING_X

; put_char(pixels, x, width, character)
push '*' ; character
push DWORD[ebp+12] ; width
push edx ; x
push DWORD[ebp+8] ; pixels
call put_char
add esp, 16
mov edx, eax

mov ebx, DWORD[ebp+16]

char_loop:
mov cl, BYTE[ebx]
cmp cl, 0
je ending_char

; put_char(pixels, x, width, character)
push ecx ; character
push DWORD[ebp+12] ; width
push edx ; x
push DWORD[ebp+8] ; pixels
call put_char
add esp, 12
pop ecx
mov edx, eax

cmp eax, -1
je exit

inc ebx
jmp char_loop

ending_char:
; put_char(pixels, x, width, character)
push '*' ; character
push DWORD[ebp+12] ; width
push edx ; x
push DWORD[ebp+8] ; pixels
call put_char
add esp, 16

set_return_value:
xor eax, eax

exit:
pop ebx
pop ebp
ret
66 changes: 31 additions & 35 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern int put_pixel(char* pixels, int x, int y);
extern int put_thin_bar(char* pixels, int x, int width);
extern int put_thick_bar(char* pixels, int x, int width);
extern int put_char(char* pixels, int x, int width, char character);
extern int encode39(char* pixels, int width, char* text);


char* read_from_file();
char* write_to_file(char* buff);
Expand All @@ -13,42 +16,40 @@ unsigned int len;

int main(int argc, char** argv)
{
if(argc != 3)
{
printf("Error: Incorrect number of arguments.\n");
printf("Correct syntax: ./program width_of_narrow_bar(1, 2 or 3) text_to_be_encoded(max 9 characters).\n ");
return 2;
}

int width = atoi(argv[1]);
if (width < 1 || width > 3) {
printf("Error: Width must be 1, 2 or 3.\n");
return 3;
}

char* text = argv[2];
if (strlen(text) > 9) {
printf("Error: Length of text to encode must be between 1 and 9 characters.\n");
return 4;
}

printf("width: %d, text: %s\n", width, text);

char* buff = read_from_file();
char* pixels = buff + 10;
pixels = buff + pixels[0];
// pixels pointer now points to the pixels section of .bmp
// if(ret == -1) {
// printf("Error 1: Text contains characters which cannot be encoded");
// return 1;
// }
// printf("return value: %d ", ret);

int ret = 10;
ret = put_char(pixels, ret, 2, '*');
ret = put_char(pixels, ret, 2, 'B');
ret = put_char(pixels, ret, 2, 'A');
ret = put_char(pixels, ret, 2, 'C');
ret = put_char(pixels, ret, 2, 'A');
put_char(pixels, ret, 2, '*');


// put_pixel(pixels, 20, 20);
// int ret = put_thick_bar(pixels, 20, 2);

// put_thin_bar(pixels, ret, 2);
int ret = encode39(pixels, width, text);
if(ret == -1) {
printf("Error: Text contains characters which cannot be encoded");
return 1;
}

write_to_file(buff);


// if(argc != 2)
// {
// printf("Input argument was not specified correctly! \n ");
// return -1;
// }

// if (result == 0) printf("No shape found.\n");
// else printf("Shape %i found.\n\n\n", result);

return 0;
}

Expand All @@ -58,10 +59,10 @@ char* read_from_file() {
imgFile = fopen("white.bmp", "rb");
if (imgFile == NULL)
{
printf("Failed to open file\n");
printf("Failed to open white.bmp\n");
exit(-1);
}
else printf("File opened successfully\n");
else printf("white.bmp opened successfully\n");

fseek(imgFile, 0, SEEK_END); /* move file pointer to end of file */
len = ftell(imgFile); /* get offset from beginning of the file */
Expand Down Expand Up @@ -95,11 +96,6 @@ char* write_to_file(char* buff) {
}
else printf("File to write to opened successfully\n");

// int width =*(int * )( & buff[18] ); // width = 600
// int width = 600;
// int height =*(int * )( & buff[22] ); // height = 50
// int height = 50;
int size = ((600 * 3 + 3) & ~3) * 50 + 54;
fwrite(buff, len, 1, imgFile);
fclose(imgFile);

Expand Down
Binary file modified output.bmp
Binary file not shown.
Binary file modified program
Binary file not shown.

0 comments on commit f139483

Please sign in to comment.