+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <Magick++.h>
+
+const unsigned int MAX_WIDTH=480;
+
+int usage(const char* name)
+{
+ std::cerr << "Usage: " << name << " IMAGE" << std::endl << "MPS801 datastream gets written to stdout" << std::endl;
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ if(argc != 2)
+ return usage(argv[0]);
+
+ auto img = Magick::Image(argv[1]);
+
+ if(img.columns() > MAX_WIDTH)
+ {
+ std::cerr << "Cropping width to " << MAX_WIDTH << "px" << std::endl;
+ img.crop(Magick::Geometry(MAX_WIDTH, img.rows(), 0, 0));
+ }
+
+ if(img.totalColors() > 2)
+ {
+ std::cerr << "Converting to bi-level image." << std::endl;
+ img.type(Magick::BilevelType);
+ }
+
+ std::vector<std::vector<uint8_t>> mps;
+ mps.insert(mps.begin(), { 0x08 });
+
+ img.modifyImage();
+ auto columns = img.columns();
+ auto rows = img.columns();
+
+ auto pixels = img.getPixels(0, 0, columns, rows);
+
+ for(size_t row=0; row < rows; row+=7)
+ {
+ std::vector<uint8_t> line(columns, 0x80);
+ for(auto subrow=0; subrow < 7; subrow++)
+ {
+ if(row+subrow >= rows)
+ break;
+ for(size_t column=0; column < columns; column++)
+ {
+ auto pixel = pixels + (row+subrow)*columns + column;
+ if((pixel->red)==0)
+ line[column] |= 1<<subrow;
+ }
+ }
+ mps.push_back(line);
+ mps.push_back({0x15, 0x0D, 0x08});
+ }
+
+ for(auto line : mps)
+ for(auto byte: line)
+ std::cout << byte;
+}