about summary refs log tree commit diff
path: root/converter/pbm/pbmtocmuwm.c
blob: 983ea4912c1d3046f1ef0fc3931fdf0aa49933f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* 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;
}