Skip to content

Commit

Permalink
Allow definition of a colour as mask. Allow inversion of image data. …
Browse files Browse the repository at this point in the history
…Added "-odb=" option.
  • Loading branch information
robabod committed Aug 3, 2021
1 parent 6c8935a commit a6d5c44
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 164 deletions.
Binary file modified 1616sq.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 55 additions & 1 deletion CommandLinePngConv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
static char THIS_FILE[]=__FILE__;
#endif

#include <map>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Expand All @@ -25,6 +27,9 @@ CCommandLinePngConv::CCommandLinePngConv()
, m_bZigZag(false)
, m_bReverse(false)
, m_bUpsideDown(false)
, m_bUseRGBMask(false)
, m_bInverseByte(false)
, m_sLeadText("db ")
{
m_pOrigin.x = m_pOrigin.y = 0;
m_pSize.x = m_pSize.y = -1;
Expand Down Expand Up @@ -76,6 +81,12 @@ void CCommandLinePngConv::ParseParam(std::string param, bool bFlag, bool bLast)
m_bReverse = false;
else if (!param.compare("usd"))
m_bUpsideDown = true;
else if (!param.compare(0, 3, "mc="))
m_bUseRGBMask = DecodeRGB3(param.substr(3));
else if (!param.compare("iimg"))
m_bInverseByte = true;
else if (!param.compare(0, 4, "odb="))
m_sLeadText = param.substr(4);
else
m_bCommandLineError = true;
}
Expand Down Expand Up @@ -110,17 +121,21 @@ std::string CCommandLinePngConv::Help()
help += "\n -ss Silent operation";
help += "\n -pos=x,y Origin of conversion image, may be negative 0,0 = top left";
help += "\n -size=x,y Size of conversion image in pixels";
help += "\n -imask Inverse mask. Default is Pixel On";
help += "\n -mask=<mask> Mask format - one of:";
help += "\n b : Output only Image (default)";
help += "\n m : Output only Mask";
help += "\n mb : Alternate Mask and Image bytes";
help += "\n bm : Alternate Image and Mask bytes";
help += "\n mmbb : Alternate Mask and Image lines";
help += "\n bbmm : Alternate Image and Mask lines";
help += "\n -mc=rgb Take mask from 3-char RGB value rather than alpha channel";
help += "\n -imask Inverse mask. Default is Pixel On";
help += "\n -iimg Inverse image. Default is White = On";
help += "\n -ostd Send output to stdout rather than a file";
help += "\n This option implies -ss to remove junk from output";
help += "\n -otxt Output as text";
help += "\n -odb=<db> Leading text when -otxt option used. Default is \"db \".";
help += "\n \"-odb=\" will give no leading text in output.";
help += "\n -obin Output as binary (default)";
help += "\n -ltr|rtl Set output left-to-right (default) or right-to-left";
help += "\n -zz ZigZag Output (alternate ltr, rtl)";
Expand Down Expand Up @@ -182,3 +197,42 @@ ZXIMAGEFORMAT CCommandLinePngConv::DecodeMask(std::string param)

return retval;
}

bool CCommandLinePngConv::DecodeRGB3(std::string param)
{
// check the string that's been passed in and decode
if (param.size() != 3 || param.find_first_not_of("0123456789abcdef") != std::string::npos)
{
m_bCommandLineError = true;
}
else
{
// it's 3 characters long and hexadecimal
// for now we'll use a map to provide the conversion from character to number.
// yes it's messy, but it will work for now. really. *cough*
std::map<char,rgbaval> hexmap;
hexmap['0'] = 0x00;
hexmap['1'] = 0x10;
hexmap['2'] = 0x20;
hexmap['3'] = 0x30;
hexmap['4'] = 0x40;
hexmap['5'] = 0x50;
hexmap['6'] = 0x60;
hexmap['7'] = 0x70;
hexmap['8'] = 0x80;
hexmap['9'] = 0x90;
hexmap['a'] = 0xa0;
hexmap['b'] = 0xb0;
hexmap['c'] = 0xc0;
hexmap['d'] = 0xd0;
hexmap['e'] = 0xe0;
hexmap['f'] = 0xf0;

m_rgbaMaskColour.btRed = hexmap[param[0]];
m_rgbaMaskColour.btGrn = hexmap[param[1]];
m_rgbaMaskColour.btBlu = hexmap[param[2]];

}

return !m_bCommandLineError;
}
5 changes: 5 additions & 0 deletions CommandLinePngConv.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@ class CCommandLinePngConv : public CCommandLine
virtual std::string Help();
std::string m_sPngFileName;
std::string m_sOutFileName;
std::string m_sLeadText;
POINT m_pOrigin;
POINT m_pSize;
RGBA m_rgbaMaskColour;
bool m_bUseRGBMask;
bool m_bUpsideDown;
bool m_bReverse;
bool m_bZigZag;
bool m_bStdOut;
bool m_bTxtOut;
bool m_bSilent;
bool m_bVersion;
bool m_bInverseByte;
bool m_bInverseMask;
ZXIMAGEFORMAT m_nMaskFormat;
protected:
bool DecodeRGB3(std::string param);
ZXIMAGEFORMAT DecodeMask(std::string param);
POINT DecodeXY(std::string param);
};
Expand Down
217 changes: 90 additions & 127 deletions ZxImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ CZxImage::CZxImage(POINT _size)
, m_bReverse(false)
, m_bUpsideDown(false)
, m_bZigZag(false)
, m_bUseRGBMask(false)
, m_bByteInvert(false)
{
// correct the X size so it's a multiple of 8
if (m_ptSize.x % 8)
Expand Down Expand Up @@ -71,7 +73,10 @@ CZxImage::ProcessRGBAImage(CRGBAImage &_rgba)
try
{
byteon = _rgba(y_idx, (8*x_idx) + b_idx).PixelIsOn(m_nGreyThreshold);
maskon = _rgba(y_idx, (8*x_idx) + b_idx).PixelIsMasked(m_nMaskThreshold);
if (!m_bUseRGBMask)
maskon = _rgba(y_idx, (8*x_idx) + b_idx).PixelIsMasked(m_nMaskThreshold);
else
maskon = _rgba(y_idx, (8*x_idx) + b_idx).PixelIsMasked(m_rgbMaskColour);
}
catch (CRGBAImage::CExBoundsViolation)
{
Expand All @@ -87,7 +92,27 @@ CZxImage::ProcessRGBAImage(CRGBAImage &_rgba)

if (m_bMaskInvert)
m_imgMask[y_idx][x_idx] = 255 - m_imgMask[y_idx][x_idx];
if (m_bByteInvert)
m_imgByte[y_idx][x_idx] = 255 - m_imgByte[y_idx][x_idx];
}
}
}

void CZxImage::SetLeadText(std::string _ss)
{
m_sLeadText = _ss;
// if the string is not empty we may need to add a space to it... unless it's a tab or space already
if (!m_sLeadText.empty())
{
// first up, ensure the "\t" is converted to a tab character...
int pos = 0;
while (std::string::npos != (pos = m_sLeadText.find("\\t", pos)))
{
m_sLeadText = m_sLeadText.substr(0, pos) + std::string("\t") + m_sLeadText.substr(pos + 2);
}
char theval = m_sLeadText[m_sLeadText.size() - 1];
if (theval != ' ' && theval != '\t')
m_sLeadText += " ";
}
}

Expand Down Expand Up @@ -159,153 +184,91 @@ std::ostream& operator<< (std::ostream& ost, const CZxImage& zxi)
}

int x_idx = x_init;

switch (zxf)
if (zxi.m_bTextOutput) ost << zxi.m_sLeadText;
for (x_line = 0; x_line < x_count; ++x_line)
{
case ZXIMAGE_FORMAT_B:
case ZXIMAGE_FORMAT_BBMM:
{
// output a line of bytes
x_idx = x_init;
if (zxi.m_bTextOutput) ost << "db ";
for (x_line = 0; x_line < x_count; ++x_line)
{
if (zxi.m_bTextOutput)
{
ost << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]);
if (x_line + 1 < x_count) ost << ",";
}
else
{
ost << zxi.m_imgByte[y_idx][x_idx];
}
x_idx += x_delta;
}
if (zxi.m_bTextOutput) ost << std::endl;
}
break;
case ZXIMAGE_FORMAT_M:
case ZXIMAGE_FORMAT_MMBB:
switch (zxf)
{
// output a line of mask
x_idx = x_init;
if (zxi.m_bTextOutput) ost << "db ";
for (x_line = 0; x_line < x_count; ++x_line)
case ZXIMAGE_FORMAT_B:
case ZXIMAGE_FORMAT_BBMM:
if (zxi.m_bTextOutput)
ost << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]);
else
ost << zxi.m_imgByte[y_idx][x_idx];
break;

case ZXIMAGE_FORMAT_M:
case ZXIMAGE_FORMAT_MMBB:
if (zxi.m_bTextOutput)
ost << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]);
else
ost << zxi.m_imgMask[y_idx][x_idx];
break;

case ZXIMAGE_FORMAT_BM:
if (zxi.m_bTextOutput)
ost << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]) << "," << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]);
else
ost << zxi.m_imgByte[y_idx][x_idx] << zxi.m_imgMask[y_idx][x_idx];
break;

case ZXIMAGE_FORMAT_MB:
if (zxi.m_bTextOutput)
ost << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]) << "," << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]);
else
ost << zxi.m_imgMask[y_idx][x_idx] << zxi.m_imgByte[y_idx][x_idx];
break;

default:
{
if (zxi.m_bTextOutput)
{
ost << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]);
if (x_line + 1 < x_count) ost << ",";
}
else
{
ost << zxi.m_imgMask[y_idx][x_idx];
}
x_idx += x_delta;
// whoops!
std::ostringstream except;
except << zxf;
throw CZxImage::CExUnknownMask(except.str());
}
if (zxi.m_bTextOutput) ost << std::endl;
break;
}
break;
case ZXIMAGE_FORMAT_BM:
{
// output alternating byte/mask
x_idx = x_init;
if (zxi.m_bTextOutput) ost << "db ";
for (x_line = 0; x_line < x_count; ++x_line)
{
if (zxi.m_bTextOutput)
{
ost << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]) << "," << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]);
if (x_line + 1 < x_count) ost << ",";
}
else
{
ost << zxi.m_imgByte[y_idx][x_idx] << zxi.m_imgMask[y_idx][x_idx];
}
x_idx += x_delta;
}
if (zxi.m_bTextOutput) ost << std::endl;
}
break;
case ZXIMAGE_FORMAT_MB:
{
// output alternating mask/byte
x_idx = x_init;
if (zxi.m_bTextOutput) ost << "db ";
for (x_line = 0; x_line < x_count; ++x_line)
{
if (zxi.m_bTextOutput)
{
ost << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]) << "," << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]);
if (x_line + 1 < x_count) ost << ",";
}
else
{
ost << zxi.m_imgMask[y_idx][x_idx] << zxi.m_imgByte[y_idx][x_idx];
}
x_idx += x_delta;
}
if (zxi.m_bTextOutput) ost << std::endl;
}
break;
default:
{
// whoops!
std::ostringstream except;
except << zxf;
throw CZxImage::CExUnknownMask(except.str());
}
break;

if (zxi.m_bTextOutput && (x_line + 1 < x_count)) ost << ",";
x_idx += x_delta;
}
if (zxi.m_bTextOutput) ost << std::endl;



// now some clean-up in case we were doing a line-by-line thing...
// we need to go through and print out the other line.
switch (zxf)
x_idx = x_init;
if (ZXIMAGE_FORMAT_BBMM == zxf || ZXIMAGE_FORMAT_MMBB == zxf)
{
case ZXIMAGE_FORMAT_BBMM:
x_idx = x_init;
if (zxi.m_bTextOutput) ost << zxi.m_sLeadText;
for (x_line = 0; x_line < x_count; ++x_line)
{
// output a line of masks now
x_idx = x_init;
if (zxi.m_bTextOutput) ost << "db ";
for (x_line = 0; x_line < x_count; ++x_line)
switch (zxf)
{
case ZXIMAGE_FORMAT_BBMM:
if (zxi.m_bTextOutput)
{
ost << static_cast<int>(zxi.m_imgMask[y_idx][x_idx]);
if (x_line + 1 < x_count) ost << ",";
}
else
{
ost << zxi.m_imgByte[y_idx][x_idx];
}
x_idx += x_delta;
}
if (zxi.m_bTextOutput) ost << std::endl;
}
break;
case ZXIMAGE_FORMAT_MMBB:
{
// output a line of bytes now
x_idx = x_init;
if (zxi.m_bTextOutput) ost << "db ";
for (x_line = 0; x_line < x_count; ++x_line)
{
ost << zxi.m_imgMask[y_idx][x_idx];
break;

case ZXIMAGE_FORMAT_MMBB:
if (zxi.m_bTextOutput)
{
ost << static_cast<int>(zxi.m_imgByte[y_idx][x_idx]);
if (x_line + 1 < x_count) ost << ",";
}
else
{
ost << zxi.m_imgByte[y_idx][x_idx];
}
x_idx += x_delta;
break;

default:
break;
}
if (zxi.m_bTextOutput) ost << std::endl;

if (zxi.m_bTextOutput && (x_line + 1 < x_count)) ost << ",";
x_idx += x_delta;
}
break;
default:
break;
if (zxi.m_bTextOutput) ost << std::endl;
}

y_idx += y_delta;
Expand Down
Loading

0 comments on commit a6d5c44

Please sign in to comment.