ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/rgbtoycc.c
Revision: 22
Committed: Mon Jul 7 22:16:37 2008 UTC (11 years ago) by wdelano
File size: 10437 byte(s)
Log Message:
initial checkin of mpeg_encode source
Line File contents
1 /*===========================================================================*
2 * rgbtoycc.c *
3 * *
4 * Procedures to convert from RGB space to YUV space *
5 * *
6 * EXPORTED PROCEDURES: *
7 * PNMtoYUV *
8 * PPMtoYUV *
9 * *
10 *===========================================================================*/
11
12 /*
13 * Copyright (c) 1995 The Regents of the University of California.
14 * All rights reserved.
15 *
16 * Permission to use, copy, modify, and distribute this software and its
17 * documentation for any purpose, without fee, and without written agreement is
18 * hereby granted, provided that the above copyright notice and the following
19 * two paragraphs appear in all copies of this software.
20 *
21 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
22 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
23 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
24 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
27 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
29 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
30 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
31 */
32
33 /*
34 * $Header: /n/picasso/project/mpeg/mpeg_dist/mpeg_encode/RCS/rgbtoycc.c,v 1.5 1995/08/14 22:32:16 smoot Exp $
35 * $Log: rgbtoycc.c,v $
36 * Revision 1.5 1995/08/14 22:32:16 smoot
37 * added better error message
38 *
39 * Revision 1.4 1995/01/19 23:09:23 eyhung
40 * Changed copyrights
41 *
42 * Revision 1.3 1994/11/12 02:12:00 keving
43 * nothing
44 *
45 * Revision 1.2 1993/12/22 19:19:01 keving
46 * nothing
47 *
48 * Revision 1.2 1993/12/22 19:19:01 keving
49 * nothing
50 *
51 * Revision 1.1 1993/07/22 22:23:43 keving
52 * nothing
53 *
54 */
55
56
57 /*==============*
58 * HEADER FILES *
59 *==============*/
60
61 #include "all.h"
62 #include "frame.h"
63 #include "fsize.h"
64 #include "rgbtoycc.h"
65
66
67 /*=====================*
68 * EXPORTED PROCEDURES *
69 *=====================*/
70
71
72 /*===========================================================================*
73 *
74 * PNMtoYUV
75 *
76 * convert PNM data into YUV data
77 *
78 * RETURNS: nothing
79 *
80 * SIDE EFFECTS: none
81 *
82 *===========================================================================*/
83 void
84 PNMtoYUV(frame)
85 MpegFrame *frame;
86 {
87 register int x, y;
88 register uint8 *dy0, *dy1;
89 register uint8 *dcr, *dcb;
90 register xel *src0, *src1;
91 register int ydivisor, cdivisor;
92 static boolean first = TRUE;
93 static float mult299[1024], mult587[1024], mult114[1024];
94 static float mult16874[1024], mult33126[1024], mult5[1024];
95 static float mult41869[1024], mult08131[1024];
96
97 if ( first ) {
98 register int index;
99 register int maxValue;
100
101 maxValue = frame->rgb_maxval;
102
103 for ( index = 0; index <= maxValue; index++ ) {
104 mult299[index] = index*0.29900;
105 mult587[index] = index*0.58700;
106 mult114[index] = index*0.11400;
107 mult16874[index] = -0.16874*index;
108 mult33126[index] = -0.33126*index;
109 mult5[index] = index*0.50000;
110 mult41869[index] = -0.41869*index;
111 mult08131[index] = -0.08131*index;
112 }
113
114 first = FALSE;
115 }
116
117 Frame_AllocYCC(frame);
118
119 /*
120 * okay. Now, convert everything into YCrCb space. (the specific
121 * numbers come from the JPEG source, jccolor.c) The conversion
122 * equations to be implemented are therefore
123 *
124 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
125 * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B
126 * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B
127 */
128
129 /* ydivisor should be a FLOAT, shouldn't it?!?! */
130
131 ydivisor = (frame->rgb_maxval + 1) >> 8; /* for normalizing values
132 * 0-255, divide by 256 */
133 cdivisor = (ydivisor << 2); /* because we're averaging 4 pixels */
134
135 for (y = 0; y < Fsize_y; y += 2) {
136 for (x = 0, src0 = frame->rgb_data[y], src1 = frame->rgb_data[y + 1],
137 dy0 = frame->orig_y[y], dy1 = frame->orig_y[y + 1],
138 dcr = frame->orig_cr[y >> 1], dcb = frame->orig_cb[y >> 1];
139 x < Fsize_x;
140 x += 2, dy0 += 2, dy1 += 2, dcr++,
141 dcb++, src0 += 2, src1 += 2) {
142
143 *dy0 = (mult299[PPM_GETR(*src0)] +
144 mult587[PPM_GETG(*src0)] +
145 mult114[PPM_GETB(*src0)]) / ydivisor;
146
147 *dy1 = (mult299[PPM_GETR(*src1)] +
148 mult587[PPM_GETG(*src1)] +
149 mult114[PPM_GETB(*src1)]) / ydivisor;
150
151 dy0[1] = (mult299[PPM_GETR(src0[1])] +
152 mult587[PPM_GETG(src0[1])] +
153 mult114[PPM_GETB(src0[1])]) / ydivisor;
154
155 dy1[1] = (mult299[PPM_GETR(src1[1])] +
156 mult587[PPM_GETG(src1[1])] +
157 mult114[PPM_GETB(src1[1])]) / ydivisor;
158
159 *dcb = ((mult16874[PPM_GETR(*src0)] +
160 mult33126[PPM_GETG(*src0)] +
161 mult5[PPM_GETB(*src0)] +
162 mult16874[PPM_GETR(*src1)] +
163 mult33126[PPM_GETG(*src1)] +
164 mult5[PPM_GETB(*src1)] +
165 mult16874[PPM_GETR(src0[1])] +
166 mult33126[PPM_GETG(src0[1])] +
167 mult5[PPM_GETB(src0[1])] +
168 mult16874[PPM_GETR(src1[1])] +
169 mult33126[PPM_GETG(src1[1])] +
170 mult5[PPM_GETB(src1[1])]) / cdivisor) + 128;
171
172 *dcr = ((mult5[PPM_GETR(*src0)] +
173 mult41869[PPM_GETG(*src0)] +
174 mult08131[PPM_GETB(*src0)] +
175 mult5[PPM_GETR(*src1)] +
176 mult41869[PPM_GETG(*src1)] +
177 mult08131[PPM_GETB(*src1)] +
178 mult5[PPM_GETR(src0[1])] +
179 mult41869[PPM_GETG(src0[1])] +
180 mult08131[PPM_GETB(src0[1])] +
181 mult5[PPM_GETR(src1[1])] +
182 mult41869[PPM_GETG(src1[1])] +
183 mult08131[PPM_GETB(src1[1])]) / cdivisor) + 128;
184
185 /* if your floating point is faster than your loads, you
186 * might consider this:
187 */
188 #ifdef BLEAH
189 *dy0 = (PPM_GETR(*src0) * 0.29900 +
190 PPM_GETG(*src0) * 0.58700 +
191 PPM_GETB(*src0) * 0.11400) / ydivisor;
192 *dy1 = (PPM_GETR(*src1) * 0.29900 +
193 PPM_GETG(*src1) * 0.58700 +
194 PPM_GETB(*src1) * 0.11400) / ydivisor;
195
196 dy0[1] = (PPM_GETR(src0[1]) * 0.29900 +
197 PPM_GETG(src0[1]) * 0.58700 +
198 PPM_GETB(src0[1]) * 0.11400) / ydivisor;
199
200 dy1[1] = (PPM_GETR(src1[1]) * 0.29900 +
201 PPM_GETG(src1[1]) * 0.58700 +
202 PPM_GETB(src1[1]) * 0.11400) / ydivisor;
203
204 *dcb = ((PPM_GETR(*src0) * -0.16874 +
205 PPM_GETG(*src0) * -0.33126 +
206 PPM_GETB(*src0) * 0.50000 +
207 PPM_GETR(*src1) * -0.16874 +
208 PPM_GETG(*src1) * -0. +
209 PPM_GETB(*src1) * 0.50000 +
210 PPM_GETR(src0[1]) * -0.16874 +
211 PPM_GETG(src0[1]) * -0.33126 +
212 PPM_GETB(src0[1]) * 0.50000 +
213 PPM_GETR(src1[1]) * -0.16874 +
214 PPM_GETG(src1[1]) * -0.33126 +
215 PPM_GETB(src1[1]) * 0.50000) / cdivisor) + 128;
216
217 *dcr = ((PPM_GETR(*src0) * 0.50000 +
218 PPM_GETG(*src0) * -0.41869 +
219 PPM_GETB(*src0) * -0.08131 +
220 PPM_GETR(*src1) * 0.50000 +
221 PPM_GETG(*src1) * -0.41869 +
222 PPM_GETB(*src1) * -0.08131 +
223 PPM_GETR(src0[1]) * 0.50000 +
224 PPM_GETG(src0[1]) * -0.41869 +
225 PPM_GETB(src0[1]) * -0.08131 +
226 PPM_GETR(src1[1]) * 0.50000 +
227 PPM_GETG(src1[1]) * -0.41869 +
228 PPM_GETB(src1[1]) * -0.08131) / cdivisor) + 128;
229 #endif
230
231 DBG_PRINT(("%3d,%3d: (%3d,%3d,%3d) --> (%3d,%3d,%3d)\n", x, y, PPM_GETR(*src0), PPM_GETG(*src0), PPM_GETB(*src0), *dy0, *dcb, *dcr));
232 }
233 }
234 }
235
236
237
238 /*===========================================================================*
239 *
240 * PPMtoYUV
241 *
242 * convert PPM data into YUV data
243 * same as PNMtoYUV, except extracts data from ppm_data, and
244 * assumes that ydivisor = 1
245 *
246 * RETURNS: nothing
247 *
248 * SIDE EFFECTS: none
249 *
250 *===========================================================================*/
251 void
252 PPMtoYUV(frame)
253 MpegFrame *frame;
254 {
255 register int x, y;
256 register uint8 *dy0, *dy1;
257 register uint8 *dcr, *dcb;
258 register uint8 *src0, *src1;
259 register int cdivisor;
260 static boolean first = TRUE;
261 static float mult299[1024], mult587[1024], mult114[1024];
262 static float mult16874[1024], mult33126[1024], mult5[1024];
263 static float mult41869[1024], mult08131[1024];
264
265 if ( first ) {
266 register int index;
267 register int maxValue;
268
269 maxValue = frame->rgb_maxval;
270
271 for ( index = 0; index <= maxValue; index++ ) {
272 mult299[index] = index*0.29900;
273 mult587[index] = index*0.58700;
274 mult114[index] = index*0.11400;
275 mult16874[index] = -0.16874*index;
276 mult33126[index] = -0.33126*index;
277 mult5[index] = index*0.50000;
278 mult41869[index] = -0.41869*index;
279 mult08131[index] = -0.08131*index;
280 }
281
282 first = FALSE;
283 }
284
285 Frame_AllocYCC(frame);
286
287 /* assume ydivisor = 1, so cdivisor = 4 */
288 if ( frame->rgb_maxval != 255 ) {
289 fprintf(stderr, "PPM max gray value != 255. Exiting.\n\tTry PNM type, not PPM\n");
290 exit(1);
291 }
292
293 cdivisor = 4;
294
295 for (y = 0; y < Fsize_y; y += 2) {
296 src0 = frame->ppm_data[y];
297 src1 = frame->ppm_data[y + 1];
298 dy0 = frame->orig_y[y];
299 dy1 = frame->orig_y[y + 1];
300 dcr = frame->orig_cr[y >> 1];
301 dcb = frame->orig_cb[y >> 1];
302
303 for ( x = 0; x < Fsize_x; x += 2, dy0 += 2, dy1 += 2, dcr++,
304 dcb++, src0 += 6, src1 += 6) {
305 *dy0 = (mult299[*src0] +
306 mult587[src0[1]] +
307 mult114[src0[2]]);
308
309 *dy1 = (mult299[*src1] +
310 mult587[src1[1]] +
311 mult114[src1[2]]);
312
313 dy0[1] = (mult299[src0[3]] +
314 mult587[src0[4]] +
315 mult114[src0[5]]);
316
317 dy1[1] = (mult299[src1[3]] +
318 mult587[src1[4]] +
319 mult114[src1[5]]);
320
321 *dcb = ((mult16874[*src0] +
322 mult33126[src0[1]] +
323 mult5[src0[2]] +
324 mult16874[*src1] +
325 mult33126[src1[1]] +
326 mult5[src1[2]] +
327 mult16874[src0[3]] +
328 mult33126[src0[4]] +
329 mult5[src0[5]] +
330 mult16874[src1[3]] +
331 mult33126[src1[4]] +
332 mult5[src1[5]]) / cdivisor) + 128;
333
334 *dcr = ((mult5[*src0] +
335 mult41869[src0[1]] +
336 mult08131[src0[2]] +
337 mult5[*src1] +
338 mult41869[src1[1]] +
339 mult08131[src1[2]] +
340 mult5[src0[3]] +
341 mult41869[src0[4]] +
342 mult08131[src0[5]] +
343 mult5[src1[3]] +
344 mult41869[src1[4]] +
345 mult08131[src1[5]]) / cdivisor) + 128;
346
347 DBG_PRINT(("%3d,%3d: (%3d,%3d,%3d) --> (%3d,%3d,%3d)\n", x, y, PPM_GETR(*src0), PPM_GETG(*src0), PPM_GETB(*src0), *dy0, *dcb, *dcr));
348 }
349 }
350 }