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