/* pbmtocmuwm.c - read a PBM image and produce a CMU window manager bitmap
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
/* 2006.10 (afu)
Changed bitrow from plain to raw, read function from pbm_readpbmrow() to
pbm_readpbmrow_packed(), write function from putc() to fwrite().
Retired bitwise transformation functions.
*/
#include "pbm.h"
static void
putinit(unsigned int const rows,
unsigned int const cols) {
const char initWriteError[] =
"CMU window manager header write error";
uint32_t const cmuwmMagic = 0xf10040bb;
int rc;
rc = pm_writebiglong(stdout, cmuwmMagic);
if (rc == -1)
pm_error(initWriteError);
rc = pm_writebiglong(stdout, cols);
if (rc == -1)
pm_error(initWriteError);
rc = pm_writebiglong(stdout, rows);
if (rc == -1)
pm_error(initWriteError);
rc = pm_writebigshort(stdout, (short) 1);
if (rc == -1)
pm_error(initWriteError);
}
int
main(int argc,
char * argv[]) {
FILE * ifP;
unsigned char * bitrow;
int rows, cols;
int format;
unsigned int row;
const char * inputFileName;
pbm_init(&argc, argv);
if (argc-1 > 1)
pm_error("Too many arguments (%u). "
"Only argument is optional input file", argc-1);
if (argc-1 == 1)
inputFileName = argv[1];
else
inputFileName = "-";
ifP = pm_openr(inputFileName);
pbm_readpbminit(ifP, &cols, &rows, &format);
bitrow = pbm_allocrow_packed(cols);
putinit(rows, cols);
/* Convert PBM raster data to CMUWM and write */
for (row = 0; row < rows; ++row) {
unsigned int const bytesPerRow = pbm_packed_bytes(cols);
unsigned char const padding =
(cols % 8 == 0) ? 0x00 : ((unsigned char) ~0 >> (cols % 8));
unsigned int i;
size_t bytesWritten;
pbm_readpbmrow_packed(ifP, bitrow, cols, format);
/* Invert all bits in row - raster formats are similar.
PBM Black:1 White:0 "Don't care" bits at end of row
CMUWM Black:0 White:1 End of row padded with 1
*/
for (i = 0; i < bytesPerRow; ++i)
bitrow[i] = ~bitrow[i];
bitrow[bytesPerRow-1] |= padding; /* Set row end pad bits */
bytesWritten = fwrite(bitrow, 1, bytesPerRow, stdout);
if (bytesWritten != bytesPerRow)
pm_error("fwrite() failed to write CMU window manager bitmap");
}
pm_close(ifP);
return 0;
}