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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
|
/* Interface header file for PPM-related functions in libnetpbm */
#ifndef _PPM_H_
#define _PPM_H_
#include <netpbm/pm_config.h>
#include <netpbm/pm.h>
#include <netpbm/pgm.h>
#ifdef __cplusplus
extern "C" {
#endif
#if 0
} /* to fake out automatic code indenters */
#endif
typedef gray pixval;
/* These are just for use in this header file */
#define PPM_MAX(a,b) ((a) > (b) ? (a) : (b))
#define PPM_MIN(a,b) ((a) < (b) ? (a) : (b))
#define PPM_OVERALLMAXVAL PGM_OVERALLMAXVAL
#define PPM_MAXMAXVAL PGM_MAXMAXVAL
typedef struct {
pixval r, g, b;
} pixel;
#define PPM_GETR(p) ((p).r)
#define PPM_GETG(p) ((p).g)
#define PPM_GETB(p) ((p).b)
/************* added definitions *****************/
#define PPM_PUTR(p,red) ((p).r = (red))
#define PPM_PUTG(p,grn) ((p).g = (grn))
#define PPM_PUTB(p,blu) ((p).b = (blu))
/**************************************************/
#define PPM_ASSIGN(p,red,grn,blu) \
do { (p).r = (red); (p).g = (grn); (p).b = (blu); } while (0)
#define PPM_EQUAL(p,q) \
( (p).r == (q).r && (p).g == (q).g && (p).b == (q).b )
/* Magic constants. */
#define PPM_MAGIC1 'P'
#define PPM_MAGIC2 '3'
#define RPPM_MAGIC2 '6'
#define PPM_FORMAT (PPM_MAGIC1 * 256 + PPM_MAGIC2)
#define RPPM_FORMAT (PPM_MAGIC1 * 256 + RPPM_MAGIC2)
#define PPM_TYPE PPM_FORMAT
#include <netpbm/ppmcmap.h>
/* Macro for turning a format number into a type number. */
#define PPM_FORMAT_TYPE(f) \
((f) == PPM_FORMAT || (f) == RPPM_FORMAT ? PPM_TYPE : PGM_FORMAT_TYPE(f))
static __inline__ pixel
ppm_whitepixel(pixval maxval) {
pixel retval;
PPM_ASSIGN(retval, maxval, maxval, maxval);
return retval;
}
static __inline__ pixel
ppm_blackpixel(void) {
pixel const retval = {0, 0, 0};
return retval;
}
void ppm_init(int * argcP, char* argv[]);
#define ppm_allocarray(cols, rows) \
((pixel**) pm_allocarray(cols, rows, sizeof(pixel)))
pixel *
ppm_allocrow(unsigned int const cols);
#define ppm_freearray(pixels, rows) pm_freearray((char**) pixels, rows)
#define ppm_freerow(pixelrow) pm_freerow(pixelrow);
pixel**
ppm_readppm(FILE * const fileP,
int * const colsP,
int * const rowsP,
pixval * const maxvalP);
void
ppm_readppminit(FILE * const fileP,
int * const colsP,
int * const rowsP,
pixval * const maxvalP,
int * const formatP);
void
ppm_readppmrow(FILE* const fileP,
pixel* const pixelrow,
int const cols,
pixval const maxval,
int const format);
void
ppm_writeppm(FILE * const fileP,
pixel** const pixels,
int const cols,
int const rows,
pixval const maxval,
int const forceplain);
void
ppm_writeppminit(FILE* const fileP,
int const cols,
int const rows,
pixval const maxval,
int const forceplain);
void
ppm_writeppmrow(FILE * const fileP,
const pixel * const pixelrow,
int const cols,
pixval const maxval,
int const forceplain);
void
ppm_check(FILE * const fileP,
enum pm_check_type const check_type,
int const format,
int const cols,
int const rows,
pixval const maxval,
enum pm_check_code * const retval_p);
void
ppm_nextimage(FILE * const fileP,
int * const eofP);
pixel
ppm_parsecolor(const char * const colorname,
pixval const maxval);
pixel
ppm_parsecolor2(const char * const colorname,
pixval const maxval,
int const closeOk);
char*
ppm_colorname(const pixel* const colorP,
pixval const maxval,
int const hexok);
void
ppm_readcolordict(const char * const fileName,
int const mustOpen,
unsigned int * const nColorsP,
const char *** const colornamesP,
pixel ** const colorsP,
colorhash_table * const chtP);
void
ppm_readcolornamefile(const char * const fileName,
int const mustOpen,
colorhash_table * const chtP,
const char *** const colornamesP);
void
ppm_freecolornames(const char ** const colornames);
#define PPM_ISGRAY(pixel) \
(PPM_GETR(pixel) == PPM_GETG(pixel) && PPM_GETR(pixel) == PPM_GETB(pixel))
/* Color scaling macro -- to make writing ppmtowhatever easier. */
#define PPM_DEPTH(newp,p,oldmaxval,newmaxval) \
PPM_ASSIGN( (newp), \
( (int) PPM_GETR(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \
( (int) PPM_GETG(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval), \
( (int) PPM_GETB(p) * (newmaxval) + (oldmaxval) / 2 ) / (oldmaxval) )
#define PPM_SQR(x) (x)*(x)
static __inline__ unsigned int
PPM_DISTANCE(pixel const p1,
pixel const p2) {
return (
PPM_SQR(PPM_GETR(p1)-PPM_GETR(p2)) +
PPM_SQR(PPM_GETG(p1)-PPM_GETG(p2)) +
PPM_SQR(PPM_GETB(p1)-PPM_GETB(p2)) );
}
#undef PPM_SQR
/* Note that because a sample can be at most 1 << 16 - 1, PPM_DISTANCE
is less than UINT_MAX. That means you can use UINT_MAX as an infinite
distance in some applications.
*/
/* Luminance, Chrominance macros. */
/* The following are weights of the red, green, and blue components
respectively in the luminance of a color. Actually, it's "luma,"
not luminance, the difference being that luminance would be a linear
combination of intensities, whereas luma is a linear combination of
gamma-adjusted intensities, as you would find in a Netpbm image.
These are from ITU-R BT.601.5. That means they probably aren't technically
right for use with PPM images, because the PPM spec says ITU-R BT.709.
The two are similar, though.
*/
#define PPM_LUMINR (0.2989)
#define PPM_LUMING (0.5866)
#define PPM_LUMINB (0.1145)
#define PPM_LUMIN(p) ( PPM_LUMINR * PPM_GETR(p) \
+ PPM_LUMING * PPM_GETG(p) \
+ PPM_LUMINB * PPM_GETB(p) )
#define PPM_CHROM_B(p) ( -0.16874 * PPM_GETR(p) \
- 0.33126 * PPM_GETG(p) \
+ 0.5 * PPM_GETB(p) )
#define PPM_CHROM_R(p) ( 0.5 * PPM_GETR(p) \
- 0.41869 * PPM_GETG(p) \
- 0.08131 * PPM_GETB(p) )
pixel
ppm_color_from_ycbcr(unsigned int const y,
int const cb,
int const cr);
/* Hue/Saturation/Value calculations */
struct hsv {
double h; /* hue (degrees) 0..360 */
double s; /* saturation (0-1) */
double v; /* value (0-1) */
};
pixel
ppm_color_from_hsv(struct hsv const hsv,
pixval const maxval);
struct hsv
ppm_hsv_from_color(pixel const color,
pixval const maxval);
static __inline__ pixval
ppm_luminosity(pixel const p) {
return (pixval)(PPM_LUMIN(p) + 0.5);
}
static __inline__ pixval
ppm_colorvalue(pixel const p) {
/*----------------------------------------------------------------------------
The color value (V is HSV) as a pixval
-----------------------------------------------------------------------------*/
return PPM_MAX(PPM_GETR(p), PPM_MAX(PPM_GETG(p), PPM_GETB(p)));
}
static __inline__ pixval
ppm_saturation(pixel const p,
pixval const maxval) {
/*----------------------------------------------------------------------------
The saturation, as a pixval (i.e. if saturation is 50% and maxval
is 100, this is 50).
-----------------------------------------------------------------------------*/
pixval const maxIntensity =
PPM_MAX(PPM_GETR(p), PPM_MAX(PPM_GETG(p), PPM_GETB(p)));
pixval const minIntensity =
PPM_MIN(PPM_GETR(p), PPM_MIN(PPM_GETG(p), PPM_GETB(p)));
pixval const range = maxIntensity - minIntensity;
return (pixval)((unsigned long)range * maxval / maxIntensity);
}
typedef enum {
/* A color from the set of universally understood colors developed
by Brent Berlin and Paul Kay.
Algorithms in libnetpbm depend on the numerical representations
of these values being as follows.
*/
BKCOLOR_GRAY = 0,
BKCOLOR_BROWN,
BKCOLOR_ORANGE,
BKCOLOR_RED,
BKCOLOR_YELLOW,
BKCOLOR_GREEN,
BKCOLOR_BLUE,
BKCOLOR_VIOLET,
BKCOLOR_PURPLE,
BKCOLOR_WHITE,
BKCOLOR_BLACK
} bk_color;
#define BKCOLOR_COUNT (BKCOLOR_BLACK+1)
bk_color
ppm_bk_color_from_color(pixel const color,
pixval const maxval);
pixel
ppm_color_from_bk_color(bk_color const bkColor,
pixval const maxval);
bk_color
ppm_bk_color_from_name(const char * const name);
const char *
ppm_name_from_bk_color(bk_color const bkColor);
#ifdef __cplusplus
}
#endif
#undef PPM_MIN
#undef PPM_MAX
#endif /*_PPM_H_*/
|