about summary refs log tree commit diff
path: root/converter/pgm/pgmtosbig.c
blob: 0a302dd84992eb2b9aa9b1c59c590627405f0962 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*=============================================================================
                                 pgmtosbig
===============================================================================

  This program converts from PGM to a simple subset of SBIG.

  By Bryan Henderson January 19, 2015.

  Contributed to the public domain by its author.
=============================================================================*/
#include <string.h>

#include "pm.h"
#include "nstring.h"
#include "pgm.h"



#define SBIG_HEADER_LENGTH  2048      /* File header length */

#define CTLZ "\x1A"


struct SbigHeader {
/*----------------------------------------------------------------------------
   The information in an SBIG file header.

   This is only the information this program cares about; the header
   may have much more information in it.
-----------------------------------------------------------------------------*/
    unsigned int height;
    unsigned int width;
    unsigned int saturationLevel;
};



static void
addUintParm(char *       const buffer,
            const char * const name,
            unsigned int const value) {

    const char * line;

    pm_asprintf(&line, "%s=%u\n\r", name, value);

    strcat(buffer, line);

    pm_strfree(line);
}



static void
writeSbigHeader(FILE *            const ofP,
                struct SbigHeader const hdr) {

    char buffer[SBIG_HEADER_LENGTH];

    memset(&buffer[0], 0x00, sizeof(buffer));

    buffer[0] = '\0';

    /* N.B. LF-CR instead of CRLF.  That's what the spec says. */

    strcat(buffer, "ST-6 Image\n\r" );

    addUintParm(buffer, "Height", hdr.height);

    addUintParm(buffer, "Width", hdr.width);

    addUintParm(buffer, "Sat_level", hdr.saturationLevel);

    strcat(buffer, "End\n\r" CTLZ);

    fwrite(buffer, 1, sizeof(buffer), ofP);
}



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

    FILE * ifP;
    gray * grayrow;
    int rows;
    int cols;
    int format;
    struct SbigHeader hdr;
    unsigned int row;
    gray maxval;
    const char * inputFile;

    pm_proginit(&argc, argv);

    if (argc-1 < 1)
        inputFile = "-";
    else {
        inputFile = argv[1];

        if (argc-1 > 2)
            pm_error("Too many arguments.  The only argument is the optional "
                     "input file name");
    }

    ifP = pm_openr(inputFile);

    pgm_readpgminit(ifP, &cols, &rows, &maxval, &format);

    grayrow = pgm_allocrow(cols);

    hdr.height = rows;
    hdr.width = cols;
    hdr.saturationLevel = maxval;

    writeSbigHeader(stdout, hdr);

    for (row = 0; row < rows; ++row) {
        unsigned int col;

        pgm_readpgmrow(ifP, grayrow, cols, maxval, format);

        for (col = 0; col < cols; ++col)
            pm_writelittleshort(stdout, grayrow[col]);
    }

    pm_close(ifP);

    return 0;
}