|
Packit |
78deda |
|
|
Packit |
78deda |
/***************************************************************************
|
|
Packit |
78deda |
|
|
Packit |
78deda |
PBMTOMDA: Convert portable bitmap to Microdesign area
|
|
Packit |
78deda |
Copyright (C) 1999,2004 John Elliott <jce@seasip.demon.co.uk>
|
|
Packit |
78deda |
|
|
Packit |
78deda |
This program is free software; you can redistribute it and/or modify
|
|
Packit |
78deda |
it under the terms of the GNU General Public License as published by
|
|
Packit |
78deda |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
78deda |
(at your option) any later version.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
This program is distributed in the hope that it will be useful,
|
|
Packit |
78deda |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
78deda |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
78deda |
GNU General Public License for more details.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
You should have received a copy of the GNU General Public License
|
|
Packit |
78deda |
along with this program; if not, write to the Free Software
|
|
Packit |
78deda |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
78deda |
|
|
Packit |
78deda |
******************************************************************************/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include <stdio.h>
|
|
Packit |
78deda |
#include <string.h>
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "pbm.h"
|
|
Packit |
78deda |
#include "mallocvar.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* I'm being somewhat conservative in the PBM -> MDA translation. I output
|
|
Packit |
78deda |
* only the MD2 format and don't allow RLE over the ends of lines.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
|
|
Packit |
78deda |
typedef unsigned char mdbyte;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static FILE *infile;
|
|
Packit |
78deda |
static mdbyte header[128];
|
|
Packit |
78deda |
static int bInvert = 0;
|
|
Packit |
78deda |
static int bScale = 0;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Encode 8 pixels as a byte */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static mdbyte
|
|
Packit |
78deda |
encode(bit ** const bits, int const row, int const col)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
int n;
|
|
Packit |
78deda |
int mask;
|
|
Packit |
78deda |
mdbyte b;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
mask = 0x80; /* initial value */
|
|
Packit |
78deda |
b = 0; /* initial value */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (n = 0; n < 8; n++) {
|
|
Packit |
78deda |
if (bits[row][col+n] == PBM_BLACK) b |= mask;
|
|
Packit |
78deda |
mask = mask >> 1;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
return b;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Translate a pbm to MD2 format, one row at a time */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static void
|
|
Packit |
78deda |
do_translation(bit ** const bits,
|
|
Packit |
78deda |
int const nOutCols,
|
|
Packit |
78deda |
int const nOutRows,
|
|
Packit |
78deda |
int const nInRows)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
int row;
|
|
Packit |
78deda |
mdbyte *mdrow; /* malloc'ed */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int const step = bScale ? 2 : 1;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
MALLOCARRAY(mdrow, nOutCols);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (mdrow == NULL)
|
|
Packit |
78deda |
pm_error("Not enough memory for conversion.");
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (row = 0; row < nOutRows; row+=step)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
int col;
|
|
Packit |
78deda |
int x1;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Encode image into non-compressed bitmap */
|
|
Packit |
78deda |
for (col = 0; col < nOutCols; ++col) {
|
|
Packit |
78deda |
mdbyte b;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (row < nInRows)
|
|
Packit |
78deda |
b = encode(bits, row, col*8);
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
b = 0xff; /* All black */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
mdrow[col] = bInvert ? b : ~b;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Encoded. Now RLE it */
|
|
Packit |
78deda |
for (col = 0; col < nOutCols; )
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
mdbyte const b = mdrow[col];
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (b != 0xFF && b != 0) /* Normal byte */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
putchar(b);
|
|
Packit |
78deda |
++col;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else /* RLE a run of 0s or 0xFFs */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
for (x1 = col; x1 < nOutCols; x1++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
if (mdrow[x1] != b) break;
|
|
Packit |
78deda |
if (x1 - col > 256) break;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
x1 -= col; /* x1 = no. of repeats */
|
|
Packit |
78deda |
if (x1 == 256) x1 = 0;
|
|
Packit |
78deda |
putchar(b);
|
|
Packit |
78deda |
putchar(x1);
|
|
Packit |
78deda |
col += x1;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
free(mdrow);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static void usage(char *s)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
printf("pbmtomda v1.01, Copyright (C) 1999,2004 John Elliott <jce@seasip.demon.co.uk>\n"
|
|
Packit |
78deda |
"This program is redistributable under the terms of the GNU General Public\n"
|
|
Packit |
78deda |
"License, version 2 or later.\n\n"
|
|
Packit |
78deda |
"Usage: %s [ -d ] [ -i ] [ -- ] [ infile ]\n\n"
|
|
Packit |
78deda |
"-d: Halve height (to compensate for the PCW aspect ratio)\n"
|
|
Packit |
78deda |
"-i: Invert colors\n"
|
|
Packit |
78deda |
"--: No more options (use if filename begins with a dash)\n",
|
|
Packit |
78deda |
s);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
exit(0);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int main(int argc, char **argv)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
int nOutRowsUnrounded; /* Before rounding up to multiple of 4 */
|
|
Packit |
78deda |
int nOutCols, nOutRows;
|
|
Packit |
78deda |
int nInCols, nInRows;
|
|
Packit |
78deda |
bit **bits;
|
|
Packit |
78deda |
int rc;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int n, optstop = 0;
|
|
Packit |
78deda |
char *fname = NULL;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pbm_init(&argc, argv);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
/* Output v2-format MDA images. Simulate MDA header...
|
|
Packit |
78deda |
* 2004-01-11: Hmm. Apparently some (but not all) MDA-reading
|
|
Packit |
78deda |
* programs insist on the program identifier being exactly
|
|
Packit |
78deda |
* 'MicroDesignPCW'. The spec does not make this clear. */
|
|
Packit |
78deda |
strcpy((char*) header, ".MDAMicroDesignPCWv1.00\r\npbm2mda\r\n");
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (n = 1; n < argc; n++)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
if (argv[n][0] == '-' && !optstop)
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
if (argv[n][1] == 'd' || argv[n][1] == 'D') bScale = 1;
|
|
Packit |
78deda |
if (argv[n][1] == 'i' || argv[n][1] == 'I') bInvert = 1;
|
|
Packit |
78deda |
if (argv[n][1] == 'h' || argv[n][1] == 'H') usage(argv[0]);
|
|
Packit |
78deda |
if (argv[n][1] == '-' && argv[n][2] == 0 && !fname) /* "--" */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
optstop = 1;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
if (argv[n][1] == '-' && (argv[n][2] == 'h' || argv[n][2] == 'H')) usage(argv[0]);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
else if (argv[n][0] && !fname) /* Filename */
|
|
Packit |
78deda |
{
|
|
Packit |
78deda |
fname = argv[n];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (fname) infile = pm_openr(fname);
|
|
Packit |
78deda |
else infile = stdin;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
bits = pbm_readpbm(infile, &nInCols, &nInRows);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
nOutRowsUnrounded = bScale ? nInRows/2 : nInRows;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
nOutRows = ((nOutRowsUnrounded + 3) / 4) * 4;
|
|
Packit |
78deda |
/* MDA wants rows a multiple of 4 */
|
|
Packit |
78deda |
nOutCols = nInCols / 8;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
rc = fwrite(header, 1, 128, stdout);
|
|
Packit |
78deda |
if (rc < 128)
|
|
Packit |
78deda |
pm_error("Unable to write header to output file. errno=%d (%s)",
|
|
Packit |
78deda |
errno, strerror(errno));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pm_writelittleshort(stdout, nOutRows);
|
|
Packit |
78deda |
pm_writelittleshort(stdout, nOutCols);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
do_translation(bits, nOutCols, nOutRows, nInRows);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pm_close(infile);
|
|
Packit |
78deda |
fflush(stdout);
|
|
Packit |
78deda |
pbm_freearray(bits, nInRows);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return 0;
|
|
Packit |
78deda |
}
|