A purely functional Scala application that processes raw image files and decodes standard 13-digit barcodes.
This project implements a complete image processing pipeline from scratch: - reading raw binary data - applying luminosity conversions - thresholding - using Run-Length Encoding (RLE) to parse and validate barcode digits
- Parses raw binary
.ppm(P6) files - Builds internal RGB data structures
- No external graphics libraries used
- Grayscale Conversion
- Converts RGB
.ppm→ grayscale.pgm - Uses standard luminosity weights
- Converts RGB
- Binarization
- Converts grayscale → black & white (
.pbm) - Uses dynamic, quadrant-based thresholding
- Handles uneven lighting conditions
- Converts grayscale → black & white (
-
Extracts pixel rows
-
Applies Run-Length Encoding (RLE) to detect bar widths
-
Normalizes sequences using custom
RatioInt -
Handles scaling and distortion
-
Digit decoding:
- Left side (Odd / Even parity)
- Right side patterns
-
Validation:
- Uses standard EAN-13 checksum
-
Types.scala
Algebraic Data Types (ADTs):- pixels
- bits
- parities
- image formats
-
Parser.scala
Byte-level parsing of.ppmheaders and data -
Convertor.scala
Image transformations:- RGB → Grayscale
- Grayscale → B&W
-
Decoder.scala
Core decoding logic:- sequence chunking
- parity matching
- checksum validation
-
Main.scala/MyBarcodes.scala
Application entry points:- define input/output paths
- orchestrate pipeline
This project uses sbt (Scala Build Tool).
- Place
.ppmimages into:MyBarcodesInput/- or
InitialBarcodes/
- Run:
sbt run- Generates processed
.pbmimages - Prints decoded 13-digit barcodes in console
- No mutable state
- Composable transformations
- Clear separation of concerns
- Works directly with raw binary formats
- No external dependencies
- Handles noise and distortion
- Uses normalization (
RatioInt) - Validates results via checksum