Blame converter/pbm/cmuwmtopbm.c

Packit 78deda
/* cmuwmtopbm.c - read a CMU window manager bitmap and produce a PBM image.
Packit 78deda
**
Packit 78deda
** Copyright (C) 1989 by Jef Poskanzer.
Packit 78deda
**
Packit 78deda
** Permission to use, copy, modify, and distribute this software and its
Packit 78deda
** documentation for any purpose and without fee is hereby granted, provided
Packit 78deda
** that the above copyright notice appear in all copies and that both that
Packit 78deda
** copyright notice and this permission notice appear in supporting
Packit 78deda
** documentation.  This software is provided "as is" without express or
Packit 78deda
** implied warranty.
Packit 78deda
*/
Packit 78deda
Packit 78deda
/* 2006.10 (afu)
Packit 78deda
   Changed bitrow from plain to raw, read function from getc() to fread(),
Packit 78deda
   write function from pbm_writepbmrow() to pbm_writepbmrow_packed().
Packit 78deda
   Retired bitwise transformation functions.
Packit 78deda
Packit 78deda
   This program does not check the pad bits at the end of each row.
Packit 78deda
*/
Packit 78deda
Packit 78deda
Packit 78deda
#include "pbm.h"
Packit 78deda
Packit 78deda
/*--------------------------
Packit 78deda
  CMUWN Header format:
Packit 78deda
Packit 78deda
  32 bit const magic = 0xf10040bb ;
Packit 78deda
  32 bit int   width;
Packit 78deda
  32 bit int   height;
Packit 78deda
  16 bit int   depth;
Packit 78deda
Packit 78deda
  values are big-endian.
Packit 78deda
--------------------------*/
Packit 78deda
Packit 78deda
static void
Packit 78deda
readCmuwmHeader(FILE *         const ifP,
Packit 78deda
                unsigned int * const colsP,
Packit 78deda
                unsigned int * const rowsP,
Packit 78deda
                unsigned int * const depthP) {
Packit 78deda
Packit 78deda
    const char * const initReadError =
Packit 78deda
        "CMU window manager header EOF / read error";
Packit 78deda
    uint32_t const cmuwmMagic = 0xf10040bb;
Packit 78deda
Packit 78deda
    long l;
Packit 78deda
    short s;
Packit 78deda
    int rc;
Packit 78deda
Packit 78deda
    rc = pm_readbiglong(ifP, &l);
Packit 78deda
    if (rc == -1 )
Packit 78deda
        pm_error("%s", initReadError);
Packit 78deda
    if ((uint32_t)l != cmuwmMagic)
Packit 78deda
        pm_error("bad magic number in CMU window manager file");
Packit 78deda
    rc = pm_readbiglong(ifP, &l);
Packit 78deda
    if (rc == -1)
Packit 78deda
        pm_error("%s", initReadError);
Packit 78deda
    *colsP = l;
Packit 78deda
    rc = pm_readbiglong(ifP, &l);
Packit 78deda
    if (rc == -1 )
Packit 78deda
        pm_error("%s", initReadError);
Packit 78deda
    *rowsP = l;
Packit 78deda
    rc = pm_readbigshort(ifP, &s);
Packit 78deda
    if (rc == -1)
Packit 78deda
        pm_error("%s", initReadError);
Packit 78deda
    *depthP = s;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
int
Packit 78deda
main(int           argc,
Packit 78deda
     const char ** argv) {
Packit 78deda
Packit 78deda
    FILE * ifP;
Packit 78deda
    unsigned char * bitrow;
Packit 78deda
    unsigned int rows, cols, depth;
Packit 78deda
    unsigned int row;
Packit 78deda
Packit 78deda
    const char * inputFileName;
Packit 78deda
Packit 78deda
    pm_proginit(&argc, argv);
Packit 78deda
Packit 78deda
    if (argc-1 > 1)
Packit 78deda
        pm_error("Too many arguments (%u).  "
Packit 78deda
                 "Only argument is optional input file", argc-1);
Packit 78deda
    if (argc-1 == 1)
Packit 78deda
        inputFileName = argv[1];
Packit 78deda
    else
Packit 78deda
        inputFileName = "-";
Packit 78deda
    
Packit 78deda
    ifP = pm_openr(inputFileName);
Packit 78deda
Packit 78deda
    readCmuwmHeader(ifP, &cols, &rows, &depth);
Packit 78deda
    if (depth != 1)
Packit 78deda
        pm_error("CMU window manager file has depth of %u, must be 1", depth);
Packit 78deda
Packit 78deda
    pbm_writepbminit(stdout, cols, rows, 0);
Packit 78deda
    bitrow = pbm_allocrow_packed(cols);
Packit 78deda
Packit 78deda
    for (row = 0; row < rows; ++row) {
Packit 78deda
        unsigned int const bytesPerRow = pbm_packed_bytes(cols);
Packit 78deda
        unsigned int byteSeq;
Packit 78deda
        size_t bytesRead;
Packit 78deda
Packit 78deda
        bytesRead = fread(bitrow, 1, bytesPerRow, ifP);
Packit 78deda
        if (bytesRead != bytesPerRow)
Packit 78deda
            pm_error("CWU window manager bitmap EOF / read error");
Packit 78deda
            
Packit 78deda
        /* Invert all bits in row - raster formats are similar.
Packit 78deda
           CMUWM Black:0 White:1  End of row padded with 1
Packit 78deda
           PBM   Black:1 White:0  End preferably padded with 0
Packit 78deda
        */
Packit 78deda
   
Packit 78deda
        for (byteSeq = 0; byteSeq < bytesPerRow; ++byteSeq)
Packit 78deda
            bitrow[byteSeq] = ~bitrow[byteSeq];
Packit 78deda
                
Packit 78deda
        pbm_writepbmrow_packed(stdout, bitrow, cols, 0);
Packit 78deda
    }
Packit 78deda
Packit 78deda
    pbm_freerow_packed(bitrow);
Packit 78deda
    pm_close(ifP);
Packit 78deda
    pm_close(stdout);
Packit 78deda
Packit 78deda
    return 0;
Packit 78deda
}