1 /*===========================================================================*
2 * ppm2eyuv.c *
3 * *
4 * program to convert ppm file to yuv file *
5 * *
6 *===========================================================================*/
7
8 /*
9 * Copyright (c) 1995 The Regents of the University of California.
10 * All rights reserved.
11 *
12 * Permission to use, copy, modify, and distribute this software and its
13 * documentation for any purpose, without fee, and without written agreement is
14 * hereby granted, provided that the above copyright notice and the following
15 * two paragraphs appear in all copies of this software.
16 *
17 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
18 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
19 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
20 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
25 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
26 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27 */
28
29 /*
30 * $Header: /n/picasso/users/keving/encode/src/RCS/readframe.c,v 1.1 1993/07/22 22:23:43 keving Exp keving $
31 * $Log: readframe.c,v $
32 * Revision 1.1 1993/07/22 22:23:43 keving
33 * nothing
34 *
35 */
36
37
38 /*==============*
39 * HEADER FILES *
40 *==============*/
41
42 #include <stdio.h>
43 #include "ansi.h"
44
45
46 typedef unsigned char uint8;
47 typedef char int8;
48 typedef int boolean;
49 #define TRUE 1
50 #define FALSE 0
51
52
53 int height, width;
54 uint8 **ppm_data;
55 uint8 **orig_y, **orig_cr, **orig_cb;
56
57
58 /*===============================*
59 * INTERNAL PROCEDURE prototypes *
60 *===============================*/
61
62 static int ReadNextInteger _ANSI_ARGS_((FILE *fpointer));
63 static boolean ReadPPM _ANSI_ARGS_((FILE *fpointer));
64 static void WriteYUV _ANSI_ARGS_((FILE *fpointer));
65 static void PPMtoYUV _ANSI_ARGS_((void));
66
67
main(int argc,char ** argv)68 void main(int argc, char **argv)
69 {
70 if ( ! ReadPPM(stdin) )
71 {
72 fprintf(stderr, "Error reading PPM input file!!!\n");
73 exit(1);
74 }
75
76 PPMtoYUV();
77
78 WriteYUV(stdout);
79 }
80
81
ReadPPM(FILE * fpointer)82 static boolean ReadPPM(FILE *fpointer)
83 {
84 char input[256];
85 uint8 junk[4096];
86 register int y;
87 int maxVal;
88
89 if ( fread(input, sizeof(char), 2, fpointer) != 2 )
90 return FALSE;
91
92 if ( strncmp(input, "P6", 2) != 0 ) /* magic number */
93 return FALSE;
94
95 width = ReadNextInteger(fpointer);
96 if ( width == -1 )
97 return FALSE;
98
99 height = ReadNextInteger(fpointer);
100 if ( height == -1 )
101 return FALSE;
102
103 maxVal = ReadNextInteger(fpointer);
104 if ( maxVal == -1 )
105 return FALSE;
106
107 if ( maxVal != 255 )
108 {
109 fprintf(stdout, "MAXVAL != 255!!! Exiting!\n");
110 fprintf(stdout, "MAXVAL war %d\n",maxVal);
111 exit(1);
112 }
113
114 ppm_data = (uint8 **) malloc(sizeof(uint8 *) * height);
115
116 for ( y = 0; y < height; y++ )
117 {
118 ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * width);
119 }
120
121 for ( y = 0; y < height; y++ )
122 {
123 fread(ppm_data[y], sizeof(char), 3*width, fpointer);
124
125 /* read the leftover stuff on the right side */
126 fread(junk, sizeof(char), 3*(width-width), fpointer);
127 }
128
129 return TRUE;
130 }
131
132
133 /*=====================*
134 * INTERNAL PROCEDURES *
135 *=====================*/
136
ReadNextInteger(FILE * fpointer)137 static int ReadNextInteger(FILE *fpointer)
138 {
139 char input[256];
140 int index;
141
142 /* skip whitespace */
143 while ( fgets(input, 2, fpointer) != NULL )
144 {
145 if ( isspace(input[0]) )
146 continue;
147
148 if ( input[0]=='#' )
149 /* read the comment lines from # to \n */
150 {
151 while ( fgets(input, 2, fpointer) != NULL )
152 {
153 if(input[0]=='\n')
154 break;
155 }
156 continue;
157 }
158
159
160 /* read rest of integer */
161 index = 1;
162 while ( fgets(&input[index], 2, fpointer) != NULL )
163 {
164 if ( isspace(input[index]) )
165 break;
166 index++;
167 }
168 input[index] = '\0';
169
170 return atoi(input);
171 }
172
173 return -1; /* end of file reached */
174 }
175
176
177
178 /*===========================================================================*
179 *
180 * PPMtoYUV
181 *
182 * convert PPM data into YUV data
183 * assumes that ydivisor = 1
184 *
185 * RETURNS: nothing
186 *
187 * SIDE EFFECTS: none
188 *
189 *===========================================================================*/
PPMtoYUV()190 void PPMtoYUV()
191 {
192 register int x, y;
193 register uint8 *dy0, *dy1;
194 register uint8 *dcr, *dcb;
195 register uint8 *src0, *src1;
196 register int cdivisor;
197 static boolean first = TRUE;
198 static float mult299[1024], mult587[1024], mult114[1024];
199 static float mult16874[1024], mult33126[1024], mult5[1024];
200 static float mult41869[1024], mult08131[1024];
201
202 if ( first )
203 {
204 register int index;
205 register int maxValue;
206
207 maxValue = 255;
208
209 for ( index = 0; index <= maxValue; index++ )
210 {
211 mult299[index] = index*0.29900;
212 mult587[index] = index*0.58700;
213 mult114[index] = index*0.11400;
214 mult16874[index] = -0.16874*index;
215 mult33126[index] = -0.33126*index;
216 mult5[index] = index*0.50000;
217 mult41869[index] = -0.41869*index;
218 mult08131[index] = -0.08131*index;
219 }
220
221 first = FALSE;
222 }
223
224 orig_y = (uint8 **) malloc(sizeof(uint8 *) * height);
225 for (y = 0; y < height; y++) {
226 orig_y[y] = (uint8 *) malloc(sizeof(uint8) * width);
227 }
228
229 orig_cr = (uint8 **) malloc(sizeof(int8 *) * height / 2);
230 for (y = 0; y < height / 2; y++) {
231 orig_cr[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
232 }
233
234 orig_cb = (uint8 **) malloc(sizeof(int8 *) * height / 2);
235 for (y = 0; y < height / 2; y++) {
236 orig_cb[y] = (uint8 *) malloc(sizeof(int8) * width / 2);
237 }
238
239 /* assume ydivisor = 1, so cdivisor = 4 */
240 cdivisor = 4;
241
242 for (y = 0; y < height; y += 2)
243 {
244 src0 = ppm_data[y];
245 src1 = ppm_data[y + 1];
246 dy0 = orig_y[y];
247 dy1 = orig_y[y + 1];
248 dcr = orig_cr[y / 2];
249 dcb = orig_cb[y / 2];
250
251 for ( x = 0; x < width; x += 2, dy0 += 2, dy1 += 2, dcr++,
252 dcb++, src0 += 6, src1 += 6)
253 {
254 *dy0 = (mult299[*src0] +
255 mult587[src0[1]] +
256 mult114[src0[2]]);
257
258 *dy1 = (mult299[*src1] +
259 mult587[src1[1]] +
260 mult114[src1[2]]);
261
262 dy0[1] = (mult299[src0[3]] +
263 mult587[src0[4]] +
264 mult114[src0[5]]);
265
266 dy1[1] = (mult299[src1[3]] +
267 mult587[src1[4]] +
268 mult114[src1[5]]);
269
270 *dcb = ((mult16874[*src0] +
271 mult33126[src0[1]] +
272 mult5[src0[2]] +
273 mult16874[*src1] +
274 mult33126[src1[1]] +
275 mult5[src1[2]] +
276 mult16874[src0[3]] +
277 mult33126[src0[4]] +
278 mult5[src0[5]] +
279 mult16874[src1[3]] +
280 mult33126[src1[4]] +
281 mult5[src1[5]]) / cdivisor) + 128;
282
283 *dcr = ((mult5[*src0] +
284 mult41869[src0[1]] +
285 mult08131[src0[2]] +
286 mult5[*src1] +
287 mult41869[src1[1]] +
288 mult08131[src1[2]] +
289 mult5[src0[3]] +
290 mult41869[src0[4]] +
291 mult08131[src0[5]] +
292 mult5[src1[3]] +
293 mult41869[src1[4]] +
294 mult08131[src1[5]]) / cdivisor) + 128;
295 }
296 }
297 }
298
299
WriteYUV(FILE * fpointer)300 static void WriteYUV(FILE *fpointer)
301 {
302 register int y;
303
304 for (y = 0; y < height; y++) /* Y */
305 fwrite(orig_y[y], 1, width, fpointer);
306
307 for (y = 0; y < height / 2; y++) /* U */
308 fwrite(orig_cb[y], 1, width / 2, fpointer);
309
310 for (y = 0; y < height / 2; y++) /* V */
311 fwrite(orig_cr[y], 1, width / 2, fpointer);
312 }
313
314