source: trunk/JPGPROC/source/gbmsrc/gbmpgm.c@ 2

Last change on this file since 2 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 4.7 KB
Line 
1/*
2
3gbmpgm.C - Poskanzers PGM format
4
5Reads as 8 bit grey image.
6Writes grey equivelent of passed in 8 bit colour data (no palette written).
7Output options: r,g,b,k (default: k)
8
9*/
10
11/*...sincludes:0:*/
12#include <stdio.h>
13#include <ctype.h>
14#include <stddef.h>
15#include <stdlib.h>
16#include <string.h>
17#include "gbm.h"
18#include "gbmhelp.h"
19
20/*...vgbm\46\h:0:*/
21/*...vgbmhelp\46\h:0:*/
22/*...e*/
23
24/*...suseful:0:*/
25#define low_byte(w) ((byte) ((w)&0x00ff) )
26#define high_byte(w) ((byte) (((w)&0xff00)>>8))
27#define make_word(a,b) (((word)a) + (((word)b) << 8))
28/*...e*/
29/*...smake_output_palette:0:*/
30#define SW4(a,b,c,d) ((a)*8+(b)*4+(c)*2+(d))
31
32static BOOLEAN make_output_palette(const GBMRGB gbmrgb[], byte grey[], const char *opt)
33 {
34 BOOLEAN k = ( gbm_find_word(opt, "k") != NULL );
35 BOOLEAN r = ( gbm_find_word(opt, "r") != NULL );
36 BOOLEAN g = ( gbm_find_word(opt, "g") != NULL );
37 BOOLEAN b = ( gbm_find_word(opt, "b") != NULL );
38 int i;
39
40 switch ( SW4(k,r,g,b) )
41 {
42 case SW4(0,0,0,0):
43 /* Default is the same as "k" */
44 case SW4(1,0,0,0):
45 for ( i = 0; i < 0x100; i++ )
46 grey[i] = (byte) ( ((word) gbmrgb[i].r * 77U +
47 (word) gbmrgb[i].g * 150U +
48 (word) gbmrgb[i].b * 29U) >> 8 );
49 return TRUE;
50 case SW4(0,1,0,0):
51 for ( i = 0; i < 0x100; i++ )
52 grey[i] = gbmrgb[i].r;
53 return TRUE;
54 case SW4(0,0,1,0):
55 for ( i = 0; i < 0x100; i++ )
56 grey[i] = gbmrgb[i].g;
57 return TRUE;
58 case SW4(0,0,0,1):
59 for ( i = 0; i < 0x100; i++ )
60 grey[i] = gbmrgb[i].b;
61 return TRUE;
62 }
63 return FALSE;
64 }
65/*...e*/
66/*...sposk stuff:0:*/
67/*...sread_byte:0:*/
68static byte read_byte(int fd)
69 {
70 byte b = 0;
71 gbm_file_read(fd, (char *) &b, 1);
72 return b;
73 }
74/*...e*/
75/*...sread_char:0:*/
76static char read_char(int fd)
77 {
78 char c;
79 while ( (c = read_byte(fd)) == '#' )
80 /* Discard to end of line */
81 while ( (c = read_byte(fd)) != '\n' )
82 ;
83 return c;
84 }
85/*...e*/
86/*...sread_num:0:*/
87static int read_num(int fd)
88 {
89 char c;
90 int num;
91
92 while ( isspace(c = read_char(fd)) )
93 ;
94 num = c - '0';
95 while ( isdigit(c = read_char(fd)) )
96 num = num * 10 + (c - '0');
97 return num;
98 }
99/*...e*/
100/*...sread_posk_header:0:*/
101static void read_posk_header(int fd, int *h1, int *h2, int *w, int *h, int *m)
102 {
103 gbm_file_lseek(fd, 0, SEEK_SET);
104 *h1 = read_byte(fd);
105 *h2 = read_byte(fd);
106 *w = read_num(fd);
107 *h = read_num(fd);
108 *m = read_num(fd);
109 }
110/*...e*/
111/*...e*/
112
113static GBMFT pgm_gbmft =
114 {
115 "Greymap",
116 "Portable Greyscale-map (binary P5 type)",
117 "PGM",
118 GBM_FT_R8|
119 GBM_FT_W8,
120 };
121
122#define GBM_ERR_PGM_BAD_M ((GBM_ERR) 100)
123
124/*...spgm_qft:0:*/
125GBM_ERR pgm_qft(GBMFT *gbmft)
126 {
127 *gbmft = pgm_gbmft;
128 return GBM_ERR_OK;
129 }
130/*...e*/
131/*...spgm_rhdr:0:*/
132GBM_ERR pgm_rhdr(const char *fn, int fd, GBM *gbm, const char *opt)
133 {
134 int h1, h2, w, h, m;
135
136 fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
137
138 read_posk_header(fd, &h1, &h2, &w, &h, &m);
139 if ( h1 != 'P' || h2 != '5' )
140 return GBM_ERR_BAD_MAGIC;
141
142 if ( w <= 0 || h <= 0 )
143 return GBM_ERR_BAD_SIZE;
144
145 if ( m <= 1 || m >= 0x100 )
146 return GBM_ERR_PGM_BAD_M;
147
148 gbm->w = w;
149 gbm->h = h;
150 gbm->bpp = 8;
151
152 return GBM_ERR_OK;
153 }
154/*...e*/
155/*...spgm_rpal:0:*/
156GBM_ERR pgm_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
157 {
158 int h1, h2, w, h, m, i;
159
160 gbm=gbm; /* Suppress 'unref arg' compiler warning */
161
162 read_posk_header(fd, &h1, &h2, &w, &h, &m);
163 for ( i = 0; i <= m; i++ )
164 gbmrgb[i].r =
165 gbmrgb[i].g =
166 gbmrgb[i].b = (byte) (i * 0xff / m);
167
168 return GBM_ERR_OK;
169 }
170/*...e*/
171/*...spgm_rdata:0:*/
172GBM_ERR pgm_rdata(int fd, GBM *gbm, byte *data)
173 {
174 int h1, h2, w, h, m, i, stride;
175 byte *p;
176
177 read_posk_header(fd, &h1, &h2, &w, &h, &m);
178
179 stride = ((gbm->w + 3) & ~3);
180 p = data + ((gbm->h - 1) * stride);
181 for ( i = gbm->h - 1; i >= 0; i-- )
182 {
183 gbm_file_read(fd, p, gbm->w);
184 p -= stride;
185 }
186 return GBM_ERR_OK;
187 }
188/*...e*/
189/*...spgm_w:0:*/
190GBM_ERR pgm_w(const char *fn, int fd, const GBM *gbm, const GBMRGB *gbmrgb, const byte *data, const char *opt)
191 {
192 char s[100+1];
193 int i, j, stride;
194 byte grey[0x100];
195 const byte *p;
196 byte *linebuf;
197
198 fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
199
200 if ( gbm->bpp != 8 )
201 return GBM_ERR_NOT_SUPP;
202
203 if ( !make_output_palette(gbmrgb, grey, opt) )
204 return GBM_ERR_BAD_OPTION;
205
206 if ( (linebuf = malloc((size_t) gbm->w)) == NULL )
207 return GBM_ERR_MEM;
208
209 sprintf(s, "P5\n%d %d\n255\n", gbm->w, gbm->h);
210 gbm_file_write(fd, s, (int) strlen(s));
211
212 stride = ((gbm->w + 3) & ~3);
213 p = data + ((gbm->h - 1) * stride);
214 for ( i = gbm->h - 1; i >= 0; i-- )
215 {
216 for ( j = 0; j < gbm->w; j++ )
217 linebuf[j] = grey[p[j]];
218 gbm_file_write(fd, linebuf, gbm->w);
219 p -= stride;
220 }
221
222 free(linebuf);
223
224 return GBM_ERR_OK;
225 }
226/*...e*/
227/*...spgm_err:0:*/
228const char *pgm_err(GBM_ERR rc)
229 {
230 switch ( (int) rc )
231 {
232 case GBM_ERR_PGM_BAD_M:
233 return "bad maximum pixel intensity";
234 }
235 return NULL;
236 }
237/*...e*/
Note: See TracBrowser for help on using the repository browser.