Start refactoring printers into own directory
This commit is contained in:
@@ -25,71 +25,85 @@
|
||||
#include <vector>
|
||||
|
||||
namespace ptprnt::graphics {
|
||||
Monochrome::Monochrome(const std::vector<uint8_t>& grayscale, uint32_t width, uint32_t height)
|
||||
: mPixels(grayscale), mWidth(width), mHeight(height) {}
|
||||
// Constructor from grayscale data
|
||||
MonochromeData::MonochromeData(const std::vector<uint8_t>& grayscale, uint32_t width, uint32_t height,
|
||||
Orientation orient)
|
||||
: stride(0),
|
||||
orientation(orient),
|
||||
width(width),
|
||||
height(height),
|
||||
mPixels(grayscale),
|
||||
mIsProcessed(false) {}
|
||||
|
||||
Monochrome::Monochrome(const std::span<uint8_t> grayscale, uint32_t width, uint32_t height)
|
||||
: mPixels(grayscale.begin(), grayscale.end()), mWidth(width), mHeight(height) {}
|
||||
MonochromeData::MonochromeData(const std::span<uint8_t> grayscale, uint32_t width, uint32_t height,
|
||||
Orientation orient)
|
||||
: stride(0),
|
||||
orientation(orient),
|
||||
width(width),
|
||||
height(height),
|
||||
mPixels(grayscale.begin(), grayscale.end()),
|
||||
mIsProcessed(false) {}
|
||||
|
||||
void Monochrome::setThreshold(uint8_t threshhold) {
|
||||
mThreshhold = threshhold;
|
||||
void MonochromeData::setThreshold(uint8_t threshold) {
|
||||
mThreshold = threshold;
|
||||
mIsProcessed = false; // Mark as needing reprocessing
|
||||
}
|
||||
|
||||
void Monochrome::invert(bool shouldInvert) {
|
||||
void MonochromeData::invert(bool shouldInvert) {
|
||||
mShouldInvert = shouldInvert;
|
||||
mIsProcessed = false; // Mark as needing reprocessing
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Monochrome::get() {
|
||||
// Calculate output size for packed format: (width + 7) / 8 bytes per row
|
||||
uint32_t stride = (mWidth + 7) / 8;
|
||||
size_t outputSize = stride * mHeight;
|
||||
std::vector<uint8_t> outPixels(outputSize, 0);
|
||||
MonochromeData MonochromeData::get() {
|
||||
if (!mIsProcessed) {
|
||||
processGrayscaleToMonochrome();
|
||||
mIsProcessed = true;
|
||||
}
|
||||
|
||||
// Pack pixels row by row for correct 2D layout
|
||||
for (uint32_t y = 0; y < mHeight; ++y) {
|
||||
for (uint32_t x = 0; x < mWidth; ++x) {
|
||||
size_t pixelIndex = y * mWidth + x; // Row-major index in input
|
||||
size_t byteIndex = y * stride + x / 8; // Byte index in packed output
|
||||
size_t bitIndex = 7 - (x % 8); // MSB first
|
||||
// Return a copy of the processed data
|
||||
MonochromeData result;
|
||||
result.bytes = bytes;
|
||||
result.stride = stride;
|
||||
result.orientation = orientation;
|
||||
result.width = width;
|
||||
result.height = height;
|
||||
result.mIsProcessed = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Convert grayscale pixel to bit based on threshold
|
||||
bool pixelOn = mPixels[pixelIndex] > mThreshhold;
|
||||
if (mShouldInvert) {
|
||||
pixelOn = !pixelOn;
|
||||
}
|
||||
void MonochromeData::processGrayscaleToMonochrome() {
|
||||
// Calculate stride based on packed monochrome data (1 bit per pixel, 8 pixels per byte)
|
||||
stride = static_cast<uint32_t>((width + 7) / 8);
|
||||
|
||||
if (pixelOn) {
|
||||
outPixels[byteIndex] |= (1 << bitIndex);
|
||||
// Create the monochrome byte array
|
||||
bytes.clear();
|
||||
bytes.resize(stride * height, 0);
|
||||
|
||||
// Convert grayscale to monochrome
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
for (uint32_t x = 0; x < width; ++x) {
|
||||
uint32_t pixelIndex = y * width + x;
|
||||
if (pixelIndex < mPixels.size()) {
|
||||
uint8_t pixelValue = mPixels[pixelIndex];
|
||||
|
||||
// Apply threshold
|
||||
bool isSet = pixelValue >= mThreshold;
|
||||
|
||||
// Apply inversion if needed
|
||||
if (mShouldInvert) {
|
||||
isSet = !isSet;
|
||||
}
|
||||
|
||||
// Set the bit in the monochrome data
|
||||
if (isSet) {
|
||||
setBit(x, y, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outPixels;
|
||||
}
|
||||
|
||||
void Monochrome::visualize() {
|
||||
auto mono = get();
|
||||
for (unsigned char pix : mono) {
|
||||
std::cout << ((pix & (1 << 7)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 6)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 5)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 4)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 3)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 2)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 1)) == 0 ? "." : "x");
|
||||
std::cout << ((pix & (1 << 0)) == 0 ? "." : "x");
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
MonochromeData Monochrome::getMonochromeData() {
|
||||
auto processedBytes = get();
|
||||
// Calculate stride based on packed monochrome data (1 bit per pixel, 8 pixels per byte)
|
||||
auto stride = static_cast<uint32_t>((mWidth + 7) / 8);
|
||||
return {std::move(processedBytes), stride, Orientation::LANDSCAPE, mWidth, mHeight};
|
||||
}
|
||||
|
||||
// MonochromeData transformation methods implementation
|
||||
// Transformation methods implementation
|
||||
void MonochromeData::transformTo(Orientation targetOrientation) {
|
||||
if (orientation == targetOrientation) {
|
||||
return; // No transformation needed
|
||||
@@ -151,7 +165,7 @@ void MonochromeData::setBit(uint32_t x, uint32_t y, bool value) {
|
||||
}
|
||||
|
||||
std::vector<uint8_t> MonochromeData::createRotatedData(Orientation targetOrientation) const {
|
||||
uint32_t newWidth, newHeight;
|
||||
uint32_t newWidth = 0, newHeight = 0;
|
||||
|
||||
// Determine new dimensions
|
||||
switch (targetOrientation) {
|
||||
@@ -182,8 +196,8 @@ std::vector<uint8_t> MonochromeData::createRotatedData(Orientation targetOrienta
|
||||
// Copy pixels with appropriate transformation
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
for (uint32_t x = 0; x < width; ++x) {
|
||||
bool pixel = getBit(x, y);
|
||||
uint32_t newX, newY;
|
||||
bool pixel = getBit(x, y);
|
||||
uint32_t newX = 0, newY = 0;
|
||||
|
||||
switch (targetOrientation) {
|
||||
case Orientation::LANDSCAPE:
|
||||
|
||||
Reference in New Issue
Block a user