ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Video-Capture-V4l/RTjpeg/codec/modules/RTmain.c
Revision: 1.1
Committed: Fri May 5 20:21:52 2000 UTC (26 years, 6 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-0_9, rel-0_902, HEAD
Log Message:
Initial check-in

File Contents

# Content
1 /*
2
3 Main Routines
4
5 This file contains most of the initialisation and control functions
6
7 (C) Justin Schoeman 1998
8
9 */
10
11 /*
12
13 Private function
14
15 Initialise all the cache-aliged data blocks
16
17 */
18
19 void
20 RTjpeg_init_data (void)
21 {
22 unsigned long dptr;
23
24 dptr = (unsigned long) &(RTjpeg_alldata[0]);
25 dptr += 32;
26 dptr = dptr >> 5;
27 dptr = dptr << 5; /* cache align data */
28
29 RTjpeg_block = (s16 *) dptr;
30 dptr += sizeof (s16) * 64;
31 RTjpeg_lqt = (s32 *) dptr;
32 dptr += sizeof (s32) * 64;
33 RTjpeg_cqt = (s32 *) dptr;
34 dptr += sizeof (s32) * 64;
35 RTjpeg_liqt = (u32 *) dptr;
36 dptr += sizeof (u32) * 64;
37 RTjpeg_ciqt = (u32 *) dptr;
38 }
39
40 /*
41
42 External Function
43
44 Re-set quality factor
45
46 Input: buf -> pointer to 128 ints for quant values store to pass back to
47 init_decompress.
48 Q -> quality factor (192=best, 32=worst)
49 */
50
51 void
52 RTjpeg_init_Q (u8 Q)
53 {
54 int i;
55 u64 qual;
56
57 qual = (u64) Q << (32 - 7); /* 32 bit FP, 255=2, 0=0 */
58
59 for (i = 0; i < 64; i++)
60 {
61 RTjpeg_lqt[i] = (s32) ((qual / ((u64) RTjpeg_lum_quant_tbl[i] << 16)) >> 3);
62 if (RTjpeg_lqt[i] == 0)
63 RTjpeg_lqt[i] = 1;
64 RTjpeg_cqt[i] = (s32) ((qual / ((u64) RTjpeg_chrom_quant_tbl[i] << 16)) >> 3);
65 if (RTjpeg_cqt[i] == 0)
66 RTjpeg_cqt[i] = 1;
67 RTjpeg_liqt[i] = (1 << 16) / (RTjpeg_lqt[i] << 3);
68 RTjpeg_ciqt[i] = (1 << 16) / (RTjpeg_cqt[i] << 3);
69 RTjpeg_lqt[i] = ((1 << 16) / RTjpeg_liqt[i]) >> 3;
70 RTjpeg_cqt[i] = ((1 << 16) / RTjpeg_ciqt[i]) >> 3;
71 }
72
73 RTjpeg_lb8 = 0;
74 while (RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]] <= 8);
75 RTjpeg_lb8--;
76 RTjpeg_cb8 = 0;
77 while (RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]] <= 8);
78 RTjpeg_cb8--;
79
80 RTjpeg_dct_init ();
81 RTjpeg_idct_init ();
82 RTjpeg_quant_init ();
83 }
84
85 /*
86
87 External Function
88
89 Initialise compression.
90
91 Input: buf -> pointer to 128 ints for quant values store to pass back to
92 init_decompress.
93 width -> width of image
94 height -> height of image
95 Q -> quality factor (192=best, 32=worst)
96
97 */
98
99 void
100 RTjpeg_init_compress (u32 * buf, int width, int height, u8 Q)
101 {
102 int i;
103 u64 qual;
104
105 RTjpeg_init_data ();
106
107 RTjpeg_width = width;
108 RTjpeg_height = height;
109
110 qual = (u64) Q << (32 - 7); /* 32 bit FP, 255=2, 0=0 */
111
112 for (i = 0; i < 64; i++)
113 {
114 RTjpeg_lqt[i] = (s32) ((qual / ((u64) RTjpeg_lum_quant_tbl[i] << 16)) >> 3);
115 if (RTjpeg_lqt[i] == 0)
116 RTjpeg_lqt[i] = 1;
117 RTjpeg_cqt[i] = (s32) ((qual / ((u64) RTjpeg_chrom_quant_tbl[i] << 16)) >> 3);
118 if (RTjpeg_cqt[i] == 0)
119 RTjpeg_cqt[i] = 1;
120 RTjpeg_liqt[i] = (1 << 16) / (RTjpeg_lqt[i] << 3);
121 RTjpeg_ciqt[i] = (1 << 16) / (RTjpeg_cqt[i] << 3);
122 RTjpeg_lqt[i] = ((1 << 16) / RTjpeg_liqt[i]) >> 3;
123 RTjpeg_cqt[i] = ((1 << 16) / RTjpeg_ciqt[i]) >> 3;
124 }
125
126 RTjpeg_lb8 = 0;
127 while (RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]] <= 8);
128 RTjpeg_lb8--;
129 RTjpeg_cb8 = 0;
130 while (RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]] <= 8);
131 RTjpeg_cb8--;
132
133 RTjpeg_dct_init ();
134 RTjpeg_quant_init ();
135
136 for (i = 0; i < 64; i++)
137 buf[i] = RTjpeg_liqt[i];
138 for (i = 0; i < 64; i++)
139 buf[64 + i] = RTjpeg_ciqt[i];
140 }
141
142 void
143 RTjpeg_init_decompress (u32 * buf, int width, int height)
144 {
145 int i;
146
147 RTjpeg_init_data ();
148
149 RTjpeg_width = width;
150 RTjpeg_height = height;
151
152 for (i = 0; i < 64; i++)
153 {
154 RTjpeg_liqt[i] = buf[i];
155 RTjpeg_ciqt[i] = buf[i + 64];
156 }
157
158 RTjpeg_lb8 = 0;
159 while (RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]] <= 8);
160 RTjpeg_lb8--;
161 RTjpeg_cb8 = 0;
162 while (RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]] <= 8);
163 RTjpeg_cb8--;
164
165 RTjpeg_idct_init ();
166
167 RTjpeg_color_init ();
168 }
169
170 int
171 RTjpeg_compress (s8 * sp, unsigned char *bp)
172 {
173 s8 *sb;
174 int i, j;
175
176 #ifdef MMX
177 emms ();
178 #endif
179
180 sb = sp;
181 /* Y */
182 for (i = 0; i < RTjpeg_height; i += 8)
183 {
184 for (j = 0; j < RTjpeg_width; j += 8)
185 {
186 RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width);
187 RTjpeg_quant (RTjpeg_block, RTjpeg_lqt);
188 sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_lb8);
189 }
190 bp += RTjpeg_width << 3;
191 }
192 /* Cr */
193 for (i = 0; i < (RTjpeg_height >> 1); i += 8)
194 {
195 for (j = 0; j < (RTjpeg_width >> 1); j += 8)
196 {
197 RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1);
198 RTjpeg_quant (RTjpeg_block, RTjpeg_cqt);
199 sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8);
200 }
201 bp += RTjpeg_width << 2;
202 }
203 /* Cb */
204 for (i = 0; i < (RTjpeg_height >> 1); i += 8)
205 {
206 for (j = 0; j < (RTjpeg_width >> 1); j += 8)
207 {
208 RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1);
209 RTjpeg_quant (RTjpeg_block, RTjpeg_cqt);
210 sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8);
211 }
212 bp += RTjpeg_width << 2;
213 }
214 #ifdef MMX
215 emms ();
216 #endif
217 return (sp - sb);
218 }
219
220 void
221 RTjpeg_decompress (s8 * sp, u8 * bp)
222 {
223 int i, j;
224
225 #ifdef MMX
226 emms ();
227 #endif
228
229 /* Y */
230 for (i = 0; i < RTjpeg_height; i += 8)
231 {
232 for (j = 0; j < RTjpeg_width; j += 8)
233 if (*sp == -1)
234 sp++;
235 else
236 {
237 sp += RTjpeg_s2b (RTjpeg_block, sp, RTjpeg_lb8, RTjpeg_liqt);
238 RTjpeg_idct (bp + j, RTjpeg_block, RTjpeg_width);
239 }
240 bp += RTjpeg_width << 3;
241 }
242 /* Cr */
243 for (i = 0; i < (RTjpeg_height >> 1); i += 8)
244 {
245 for (j = 0; j < (RTjpeg_width >> 1); j += 8)
246 if (*sp == -1)
247 sp++;
248 else
249 {
250 sp += RTjpeg_s2b (RTjpeg_block, sp, RTjpeg_cb8, RTjpeg_ciqt);
251 RTjpeg_idct (bp + j, RTjpeg_block, RTjpeg_width >> 1);
252 }
253 bp += RTjpeg_width << 2;
254 }
255 /* Cb */
256 for (i = 0; i < (RTjpeg_height >> 1); i += 8)
257 {
258 for (j = 0; j < (RTjpeg_width >> 1); j += 8)
259 if (*sp == -1)
260 sp++;
261 else
262 {
263 sp += RTjpeg_s2b (RTjpeg_block, sp, RTjpeg_cb8, RTjpeg_ciqt);
264 RTjpeg_idct (bp + j, RTjpeg_block, RTjpeg_width >> 1);
265 }
266 bp += RTjpeg_width << 2;
267 }
268 #ifdef MMX
269 emms ();
270 #endif
271 }
272
273 /*
274 External Function
275
276 Initialise additional data structures for motion compensation
277
278 */
279
280 void
281 RTjpeg_init_mcompress (void)
282 {
283 unsigned long tmp;
284
285 if (!RTjpeg_old)
286 {
287 RTjpeg_old = malloc (((RTjpeg_width * RTjpeg_height) << 1) + (RTjpeg_width * RTjpeg_height) + 32);
288 tmp = (unsigned long) RTjpeg_old;
289 tmp += 32;
290 tmp = tmp >> 5;
291 RTjpeg_old = (s16 *) (tmp << 5);
292 }
293 if (!RTjpeg_old)
294 {
295 fprintf (stderr, "RTjpeg: Could not allocate memory\n");
296 exit (-1);
297 }
298 bzero (RTjpeg_old, ((RTjpeg_width * RTjpeg_height) + ((RTjpeg_width * RTjpeg_height) >> 1)) << 1);
299 }
300
301 #ifdef MMX
302
303 int
304 RTjpeg_bcomp (s16 * old, mmx_t * mask)
305 {
306 int i;
307 mmx_t *mold = (mmx_t *) old;
308 mmx_t *mblock = (mmx_t *) RTjpeg_block;
309 mmx_t result;
310 static mmx_t neg = (mmx_t) (unsigned long long) 0xffffffffffffffffULL;
311
312 movq_m2r (*mask, mm7);
313 movq_m2r (neg, mm6);
314 pxor_r2r (mm5, mm5);
315
316 for (i = 0; i < 8; i++)
317 {
318 movq_m2r (*(mblock++), mm0);
319 movq_m2r (*(mblock++), mm2);
320 movq_m2r (*(mold++), mm1);
321 movq_m2r (*(mold++), mm3);
322 psubsw_r2r (mm1, mm0);
323 psubsw_r2r (mm3, mm2);
324 movq_r2r (mm0, mm1);
325 movq_r2r (mm2, mm3);
326 pcmpgtw_r2r (mm7, mm0);
327 pcmpgtw_r2r (mm7, mm2);
328 pxor_r2r (mm6, mm1);
329 pxor_r2r (mm6, mm3);
330 pcmpgtw_r2r (mm7, mm1);
331 pcmpgtw_r2r (mm7, mm3);
332 por_r2r (mm0, mm5);
333 por_r2r (mm2, mm5);
334 por_r2r (mm1, mm5);
335 por_r2r (mm3, mm5);
336 }
337 movq_r2m (mm5, result);
338
339 if (result.q)
340 {
341 if (!RTjpeg_mtest)
342 for (i = 0; i < 16; i++)
343 ((u64 *) old)[i] = ((u64 *) RTjpeg_block)[i];
344 return 0;
345 }
346 // printf(".");
347 return 1;
348 }
349
350 #else
351 int
352 RTjpeg_bcomp (s16 * old, u16 * mask)
353 {
354 int i;
355
356 for (i = 0; i < 64; i++)
357 if (abs (old[i] - RTjpeg_block[i]) > *mask)
358 {
359 if (!RTjpeg_mtest)
360 for (i = 0; i < 16; i++)
361 ((u64 *) old)[i] = ((u64 *) RTjpeg_block)[i];
362 return 0;
363 }
364 return 1;
365 }
366 #endif
367
368 void
369 RTjpeg_set_test (int i)
370 {
371 RTjpeg_mtest = i;
372 }
373
374 int
375 RTjpeg_mcompress (s8 * sp, unsigned char *bp, u16 lmask, u16 cmask,
376 int x, int y, int w, int h)
377 {
378 s8 *sb;
379 s16 *block;
380 int i, j;
381
382 #ifdef MMX
383 emms ();
384 RTjpeg_lmask = (mmx_t) (((u64) lmask << 48) | ((u64) lmask << 32) | ((u64) lmask << 16) | lmask);
385 RTjpeg_cmask = (mmx_t) (((u64) cmask << 48) | ((u64) cmask << 32) | ((u64) cmask << 16) | cmask);
386 #else
387 RTjpeg_lmask = lmask;
388 RTjpeg_cmask = cmask;
389 #endif
390
391 w += x;
392 h += y;
393
394 sb = sp;
395 block = RTjpeg_old;
396 /* Y */
397 for (i = 0; i < RTjpeg_height; i += 8)
398 {
399 if (i >= y && i < h)
400 {
401 for (j = x; j < w; j += 8)
402 {
403 RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width);
404 RTjpeg_quant (RTjpeg_block, RTjpeg_lqt);
405 if (RTjpeg_bcomp (block, &RTjpeg_lmask))
406 *((u8 *) sp++) = 255;
407 else
408 sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_lb8);
409 block += 64;
410 }
411 }
412 bp += RTjpeg_width << 3;
413 }
414
415 y >>= 1; h >>= 1;
416
417 /* Cr */
418 for (i = 0; i < (RTjpeg_height >> 1); i += 8)
419 {
420 if (i >= y && i < h)
421 {
422 for (j = x >> 1; j < (w >> 1); j += 8)
423 {
424 RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1);
425 RTjpeg_quant (RTjpeg_block, RTjpeg_cqt);
426 if (RTjpeg_bcomp (block, &RTjpeg_cmask))
427 *((u8 *) sp++) = 255;
428 else
429 sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8);
430 block += 64;
431 }
432 }
433 bp += RTjpeg_width << 2;
434 }
435 /* Cb */
436 for (i = 0; i < (RTjpeg_height >> 1); i += 8)
437 {
438 if (i >= y && i < h)
439 {
440 for (j = x >> 1; j < (w >> 1); j += 8)
441 {
442 RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1);
443 RTjpeg_quant (RTjpeg_block, RTjpeg_cqt);
444 if (RTjpeg_bcomp (block, &RTjpeg_cmask))
445 *((u8 *) sp++) = 255;
446 else
447 sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8);
448 block += 64;
449 }
450 }
451 bp += RTjpeg_width << 2;
452 }
453 #ifdef MMX
454 emms ();
455 #endif
456 return (sp - sb);
457 }
458