source: trunk/JPGPROC/source/gbmsrc/gbmppm.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: 3.7 KB
Line 
1/*
2
3gbmppm.c - Poskanzers PPM format
4
5Reads and writes 24 bit RGB.
6
7*/
8
9/*...sincludes:0:*/
10#include <stdio.h>
11#include <ctype.h>
12#include <stddef.h>
13#include <stdlib.h>
14#include <string.h>
15#include "gbm.h"
16#include "gbmhelp.h"
17
18/*...vgbm\46\h:0:*/
19/*...vgbmhelp\46\h:0:*/
20/*...e*/
21
22/*...suseful:0:*/
23#define low_byte(w) ((byte) ((w)&0x00ff) )
24#define high_byte(w) ((byte) (((w)&0xff00)>>8))
25#define make_word(a,b) (((word)a) + (((word)b) << 8))
26/*...e*/
27/*...sposk stuff:0:*/
28/*...sread_byte:0:*/
29static byte read_byte(int fd)
30 {
31 byte b = 0;
32 gbm_file_read(fd, (char *) &b, 1);
33 return b;
34 }
35/*...e*/
36/*...sread_char:0:*/
37static char read_char(int fd)
38 {
39 char c;
40 while ( (c = read_byte(fd)) == '#' )
41 /* Discard to end of line */
42 while ( (c = read_byte(fd)) != '\n' )
43 ;
44 return c;
45 }
46/*...e*/
47/*...sread_num:0:*/
48static int read_num(int fd)
49 {
50 char c;
51 int num;
52
53 while ( isspace(c = read_char(fd)) )
54 ;
55 num = c - '0';
56 while ( isdigit(c = read_char(fd)) )
57 num = num * 10 + (c - '0');
58 return num;
59 }
60/*...e*/
61/*...sread_posk_header:0:*/
62static void read_posk_header(int fd, int *h1, int *h2, int *w, int *h, int *m)
63 {
64 gbm_file_lseek(fd, 0, SEEK_SET);
65 *h1 = read_byte(fd);
66 *h2 = read_byte(fd);
67 *w = read_num(fd);
68 *h = read_num(fd);
69 *m = read_num(fd);
70 }
71/*...e*/
72/*...e*/
73
74static GBMFT ppm_gbmft =
75 {
76 "Pixmap",
77 "Portable Pixel-map (binary P6 type)",
78 "PPM",
79 GBM_FT_R24|
80 GBM_FT_W24,
81 };
82
83#define GBM_ERR_PPM_BAD_M ((GBM_ERR) 200)
84
85/*...srgb_bgr:0:*/
86static void rgb_bgr(const byte *p, byte *q, int n)
87 {
88 while ( n-- )
89 {
90 byte r = *p++;
91 byte g = *p++;
92 byte b = *p++;
93
94 *q++ = b;
95 *q++ = g;
96 *q++ = r;
97 }
98 }
99/*...e*/
100
101/*...sppm_qft:0:*/
102GBM_ERR ppm_qft(GBMFT *gbmft)
103 {
104 *gbmft = ppm_gbmft;
105 return GBM_ERR_OK;
106 }
107/*...e*/
108/*...sppm_rhdr:0:*/
109GBM_ERR ppm_rhdr(const char *fn, int fd, GBM *gbm, const char *opt)
110 {
111 int h1, h2, w, h, m;
112
113 fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
114
115 read_posk_header(fd, &h1, &h2, &w, &h, &m);
116 if ( h1 != 'P' || h2 != '6' )
117 return GBM_ERR_BAD_MAGIC;
118
119 if ( w <= 0 || h <= 0 )
120 return GBM_ERR_BAD_SIZE;
121
122 if ( m <= 1 || m >= 0x100 )
123 return GBM_ERR_PPM_BAD_M;
124
125 gbm->w = w;
126 gbm->h = h;
127 gbm->bpp = 24;
128
129 return GBM_ERR_OK;
130 }
131/*...e*/
132/*...sppm_rpal:0:*/
133GBM_ERR ppm_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
134 {
135 fd=fd; gbm=gbm; gbmrgb=gbmrgb; /* Suppress 'unref arg' compiler warnings */
136
137 return GBM_ERR_OK;
138 }
139/*...e*/
140/*...sppm_rdata:0:*/
141GBM_ERR ppm_rdata(int fd, GBM *gbm, byte *data)
142 {
143 int h1, h2, w, h, m, i, stride;
144 byte *p;
145
146 read_posk_header(fd, &h1, &h2, &w, &h, &m);
147
148 stride = ((gbm->w * 3 + 3) & ~3);
149 p = data + ((gbm->h - 1) * stride);
150 for ( i = gbm->h - 1; i >= 0; i-- )
151 {
152 gbm_file_read(fd, p, gbm->w * 3);
153 rgb_bgr(p, p, gbm->w);
154 p -= stride;
155 }
156 if ( m < 255 )
157 for ( i = 0; i < stride*h; i++ )
158 p[i] = (byte) ((p[i]*255U)/(unsigned)m);
159 return GBM_ERR_OK;
160 }
161/*...e*/
162/*...sppm_w:0:*/
163GBM_ERR ppm_w(const char *fn, int fd, const GBM *gbm, const GBMRGB *gbmrgb, const byte *data, const char *opt)
164 {
165 char s[100+1];
166 int i, stride;
167 const byte *p;
168 byte *linebuf;
169
170 fn=fn; gbmrgb=gbmrgb; opt=opt; /* Suppress 'unref arg' compiler warnings */
171
172 if ( gbm->bpp != 24 )
173 return GBM_ERR_NOT_SUPP;
174
175 if ( (linebuf = malloc((size_t) (gbm->w * 3))) == NULL )
176 return GBM_ERR_MEM;
177
178 sprintf(s, "P6\n%d %d\n255\n", gbm->w, gbm->h);
179 gbm_file_write(fd, s, (int) strlen(s));
180
181 stride = ((gbm->w * 3 + 3) & ~3);
182 p = data + ((gbm->h - 1) * stride);
183 for ( i = gbm->h - 1; i >= 0; i-- )
184 {
185 rgb_bgr(p, linebuf, gbm->w);
186 gbm_file_write(fd, linebuf, gbm->w * 3);
187 p -= stride;
188 }
189
190 free(linebuf);
191
192 return GBM_ERR_OK;
193 }
194/*...e*/
195/*...sppm_err:0:*/
196const char *ppm_err(GBM_ERR rc)
197 {
198 switch ( (int) rc )
199 {
200 case GBM_ERR_PPM_BAD_M:
201 return "bad maximum pixel intensity";
202 }
203 return NULL;
204 }
205/*...e*/
Note: See TracBrowser for help on using the repository browser.