about summary refs log tree commit diff
path: root/converter/pbm/brushtopbm.c
blob: c50fe8a153aa79331ad65d49636a8c6e16fbe427 (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
107
108
109
110
111
/* brushtopbm.c - read a doodle brush file and write a PBM image
**
** Copyright (C) 1988 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.
*/

#include "pbm.h"

#define HEADERSIZE 16   /* 16 is just a guess at the header size */



static void
getinit(FILE *         const ifP,
        unsigned int * const colsP,
        unsigned int * const rowsP) {

    unsigned char header[HEADERSIZE];
    size_t bytesRead;

    bytesRead = fread(header, sizeof(header), 1, ifP);
    if (bytesRead !=1)
        pm_error("Error reading header");   

    if (header[0] != 1)
        pm_error("bad magic number 1");
    if (header[1] != 0)
        pm_error("bad magic number 2");

    *colsP =  (header[2] << 8) + header[3];  /* Max 65535 */
    *rowsP =  (header[4] << 8) + header[5];  /* Max 65535 */
}



static void
validateEof(FILE * const ifP) {

    int rc;
    rc = getc(ifP);
    if (rc != EOF)
        pm_message("Extraneous data at end of file");
}


/*
   The routine for converting the raster closely resembles the pbm
   case of pnminvert.  Input is padded up to 16 bit border.
   afu December 2013
 */



int
main(int argc, const char ** argv)  {

    FILE * ifP;
    bit * bitrow;
    unsigned int rows, cols, row;

    pm_proginit(&argc, argv);

    if (argc-1 > 0) {
        ifP = pm_openr(argv[1]);
        if (argc-1 > 1)
            pm_error("Too many arguments (%u).  "
                     "The only argument is the brush file name.", argc-1);
    } else
        ifP = stdin;

    getinit(ifP, &cols, &rows);

    pbm_writepbminit(stdout, cols, rows, 0);

    bitrow = pbm_allocrow_packed(cols + 16);

    for (row = 0; row < rows; ++row) {
        unsigned int const inRowBytes = ((cols + 15) / 16) * 2;
        unsigned int i;
        size_t bytesRead;

        bytesRead = fread (bitrow, 1, inRowBytes, ifP); 
        if (bytesRead != inRowBytes)
            pm_error("Error reading a row of data from brushfile");

        for (i = 0; i < inRowBytes; ++i)
            bitrow[i] = ~bitrow[i];

        /* Clean off remainder of fractional last character */
        if (cols % 8 > 0) {
            unsigned int const colChars = pbm_packed_bytes(cols);
            bitrow[colChars-1] >>= 8 - cols % 8;
            bitrow[colChars-1] <<= 8 - cols % 8;
        }

        pbm_writepbmrow_packed(stdout, bitrow, cols, 0);
    }

    validateEof(ifP);

    pm_close(ifP);
    pm_close(stdout);
    
    return 0;
}