[svn] / branches / dev-api-3 / xvidcore / src / image / image.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/xvidcore/src/image/image.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 807 - (view) (download)

1 : albeu 315 /**************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * image stuff
5 :     *
6 : chl 530 * This program is an implementation of a part of one or more MPEG-4
7 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
8 :     * to use this software module in hardware or software products are
9 :     * advised that its use may infringe existing patents or copyrights, and
10 :     * any such use would be at such party's own risk. The original
11 :     * developer of this software module and his/her company, and subsequent
12 :     * editors and their companies, will have no liability for use of this
13 :     * software or modifications or derivatives thereof.
14 :     *
15 : albeu 315 * This program is free software; you can redistribute it and/or modify
16 :     * it under the terms of the GNU General Public License as published by
17 :     * the Free Software Foundation; either version 2 of the License, or
18 :     * (at your option) any later version.
19 :     *
20 :     * This program is distributed in the hope that it will be useful,
21 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 :     * GNU General Public License for more details.
24 :     *
25 :     * You should have received a copy of the GNU General Public License
26 :     * along with this program; if not, write to the Free Software
27 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 :     *
29 :     *************************************************************************/
30 :    
31 :     /**************************************************************************
32 :     *
33 :     * History:
34 :     *
35 : Isibaar 579 * 05.10.2002 support for interpolated images in qpel mode - Isibaar
36 : albeu 315 * 01.05.2002 BFRAME image-based u,v interpolation
37 :     * 22.04.2002 added some B-frame support
38 :     * 14.04.2002 added image_dump_yuvpgm(), added image_mad()
39 :     * XVID_CSP_USER input support
40 : Isibaar 579 * 09.04.2002 PSNR calculations - Isibaar
41 : albeu 315 * 06.04.2002 removed interlaced edging from U,V blocks (as per spec)
42 :     * 26.03.2002 interlacing support (field-based edging in set_edges)
43 :     * 26.01.2002 rgb555, rgb565
44 :     * 07.01.2001 commented u,v interpolation (not required for uv-block-based)
45 :     * 23.12.2001 removed #ifdefs, added function pointers + init_common()
46 :     * 22.12.2001 cpu #ifdefs
47 :     * 19.12.2001 image_dump(); useful for debugging
48 :     * 6.12.2001 inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>
49 :     *
50 :     *************************************************************************/
51 :    
52 :     #include <stdlib.h>
53 :     #include <string.h> // memcpy, memset
54 :     #include <math.h>
55 :    
56 :     #include "../portab.h"
57 : suxen_drol 631 #include "../global.h"
58 : albeu 315 #include "../xvid.h"
59 :     #include "image.h"
60 :     #include "colorspace.h"
61 :     #include "interpolate8x8.h"
62 : suxen_drol 702 #include "reduced.h"
63 : albeu 315 #include "../divx4.h"
64 :     #include "../utils/mem_align.h"
65 :    
66 : suxen_drol 631 #include "font.h"
67 :    
68 : albeu 315 #define SAFETY 64
69 :     #define EDGE_SIZE2 (EDGE_SIZE/2)
70 :    
71 :    
72 :     int32_t
73 :     image_create(IMAGE * image,
74 :     uint32_t edged_width,
75 :     uint32_t edged_height)
76 :     {
77 :     const uint32_t edged_width2 = edged_width / 2;
78 :     const uint32_t edged_height2 = edged_height / 2;
79 :     uint32_t i;
80 :    
81 :     image->y =
82 :     xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE);
83 :     if (image->y == NULL) {
84 :     return -1;
85 :     }
86 :    
87 :     for (i = 0; i < edged_width * edged_height + SAFETY; i++) {
88 :     image->y[i] = 0;
89 :     }
90 :    
91 :     image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE);
92 :     if (image->u == NULL) {
93 :     xvid_free(image->y);
94 :     return -1;
95 :     }
96 :     image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE);
97 :     if (image->v == NULL) {
98 :     xvid_free(image->u);
99 :     xvid_free(image->y);
100 :     return -1;
101 :     }
102 :    
103 :     image->y += EDGE_SIZE * edged_width + EDGE_SIZE;
104 :     image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2;
105 :     image->v += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2;
106 :    
107 :     return 0;
108 :     }
109 :    
110 :    
111 :    
112 :     void
113 :     image_destroy(IMAGE * image,
114 :     uint32_t edged_width,
115 :     uint32_t edged_height)
116 :     {
117 :     const uint32_t edged_width2 = edged_width / 2;
118 :    
119 :     if (image->y) {
120 :     xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE));
121 :     }
122 :     if (image->u) {
123 :     xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2));
124 :     }
125 :     if (image->v) {
126 :     xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2));
127 :     }
128 :     }
129 :    
130 :    
131 :     void
132 :     image_swap(IMAGE * image1,
133 :     IMAGE * image2)
134 :     {
135 :     uint8_t *tmp;
136 :    
137 :     tmp = image1->y;
138 :     image1->y = image2->y;
139 :     image2->y = tmp;
140 :    
141 :     tmp = image1->u;
142 :     image1->u = image2->u;
143 :     image2->u = tmp;
144 :    
145 :     tmp = image1->v;
146 :     image1->v = image2->v;
147 :     image2->v = tmp;
148 :     }
149 :    
150 :    
151 :     void
152 :     image_copy(IMAGE * image1,
153 :     IMAGE * image2,
154 :     uint32_t edged_width,
155 :     uint32_t height)
156 :     {
157 :     memcpy(image1->y, image2->y, edged_width * height);
158 :     memcpy(image1->u, image2->u, edged_width * height / 4);
159 :     memcpy(image1->v, image2->v, edged_width * height / 4);
160 :     }
161 :    
162 :    
163 :     void
164 :     image_setedges(IMAGE * image,
165 :     uint32_t edged_width,
166 :     uint32_t edged_height,
167 :     uint32_t width,
168 : h 543 uint32_t height)
169 : albeu 315 {
170 :     const uint32_t edged_width2 = edged_width / 2;
171 :     const uint32_t width2 = width / 2;
172 :     uint32_t i;
173 :     uint8_t *dst;
174 :     uint8_t *src;
175 :    
176 :    
177 :     dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width);
178 :     src = image->y;
179 :    
180 :     for (i = 0; i < EDGE_SIZE; i++) {
181 : h 543 memset(dst, *src, EDGE_SIZE);
182 :     memcpy(dst + EDGE_SIZE, src, width);
183 :     memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),
184 :     EDGE_SIZE);
185 : albeu 315 dst += edged_width;
186 :     }
187 :    
188 :     for (i = 0; i < height; i++) {
189 :     memset(dst, *src, EDGE_SIZE);
190 :     memset(dst + edged_width - EDGE_SIZE, src[width - 1], EDGE_SIZE);
191 :     dst += edged_width;
192 :     src += edged_width;
193 :     }
194 :    
195 :     src -= edged_width;
196 :     for (i = 0; i < EDGE_SIZE; i++) {
197 : h 543 memset(dst, *src, EDGE_SIZE);
198 :     memcpy(dst + EDGE_SIZE, src, width);
199 :     memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),
200 : albeu 315 EDGE_SIZE);
201 :     dst += edged_width;
202 :     }
203 :    
204 :    
205 :     //U
206 :     dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);
207 :     src = image->u;
208 :    
209 :     for (i = 0; i < EDGE_SIZE2; i++) {
210 :     memset(dst, *src, EDGE_SIZE2);
211 :     memcpy(dst + EDGE_SIZE2, src, width2);
212 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
213 :     EDGE_SIZE2);
214 :     dst += edged_width2;
215 :     }
216 :    
217 :     for (i = 0; i < height / 2; i++) {
218 :     memset(dst, *src, EDGE_SIZE2);
219 :     memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2);
220 :     dst += edged_width2;
221 :     src += edged_width2;
222 :     }
223 :     src -= edged_width2;
224 :     for (i = 0; i < EDGE_SIZE2; i++) {
225 :     memset(dst, *src, EDGE_SIZE2);
226 :     memcpy(dst + EDGE_SIZE2, src, width2);
227 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
228 :     EDGE_SIZE2);
229 :     dst += edged_width2;
230 :     }
231 :    
232 :    
233 :     // V
234 :     dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);
235 :     src = image->v;
236 :    
237 :     for (i = 0; i < EDGE_SIZE2; i++) {
238 :     memset(dst, *src, EDGE_SIZE2);
239 :     memcpy(dst + EDGE_SIZE2, src, width2);
240 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
241 :     EDGE_SIZE2);
242 :     dst += edged_width2;
243 :     }
244 :    
245 :     for (i = 0; i < height / 2; i++) {
246 :     memset(dst, *src, EDGE_SIZE2);
247 :     memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2);
248 :     dst += edged_width2;
249 :     src += edged_width2;
250 :     }
251 :     src -= edged_width2;
252 :     for (i = 0; i < EDGE_SIZE2; i++) {
253 :     memset(dst, *src, EDGE_SIZE2);
254 :     memcpy(dst + EDGE_SIZE2, src, width2);
255 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
256 :     EDGE_SIZE2);
257 :     dst += edged_width2;
258 :     }
259 :     }
260 :    
261 : chl 530 // bframe encoding requires image-based u,v interpolation
262 : albeu 315 void
263 :     image_interpolate(const IMAGE * refn,
264 :     IMAGE * refh,
265 :     IMAGE * refv,
266 :     IMAGE * refhv,
267 :     uint32_t edged_width,
268 :     uint32_t edged_height,
269 : Isibaar 579 uint32_t quarterpel,
270 : albeu 315 uint32_t rounding)
271 :     {
272 : Isibaar 586 const uint32_t offset = EDGE_SIZE2 * (edged_width + 1); // we only interpolate half of the edge area
273 : albeu 315 const uint32_t stride_add = 7 * edged_width;
274 : Isibaar 586 /*
275 : chl 530 #ifdef BFRAMES
276 : albeu 315 const uint32_t edged_width2 = edged_width / 2;
277 :     const uint32_t edged_height2 = edged_height / 2;
278 :     const uint32_t offset2 = EDGE_SIZE2 * (edged_width2 + 1);
279 :     const uint32_t stride_add2 = 7 * edged_width2;
280 : chl 530 #endif
281 : Isibaar 586 */
282 : albeu 315 uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;
283 :     uint32_t x, y;
284 :    
285 :    
286 :     n_ptr = refn->y;
287 :     h_ptr = refh->y;
288 :     v_ptr = refv->y;
289 :     hv_ptr = refhv->y;
290 :    
291 :     n_ptr -= offset;
292 :     h_ptr -= offset;
293 :     v_ptr -= offset;
294 :     hv_ptr -= offset;
295 :    
296 : Isibaar 579 if(quarterpel) {
297 :    
298 : Isibaar 586 for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {
299 :     for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {
300 : Isibaar 579 interpolate8x8_6tap_lowpass_h(h_ptr, n_ptr, edged_width, rounding);
301 :     interpolate8x8_6tap_lowpass_v(v_ptr, n_ptr, edged_width, rounding);
302 : albeu 315
303 : Isibaar 579 n_ptr += 8;
304 :     h_ptr += 8;
305 :     v_ptr += 8;
306 :     }
307 :    
308 : Isibaar 586 n_ptr += EDGE_SIZE;
309 :     h_ptr += EDGE_SIZE;
310 :     v_ptr += EDGE_SIZE;
311 :    
312 : Isibaar 579 h_ptr += stride_add;
313 :     v_ptr += stride_add;
314 :     n_ptr += stride_add;
315 : albeu 315 }
316 : Isibaar 579
317 :     h_ptr = refh->y;
318 :     h_ptr -= offset;
319 :    
320 : Isibaar 586 for (y = 0; y < (edged_height - EDGE_SIZE); y = y + 8) {
321 :     for (x = 0; x < (edged_width - EDGE_SIZE); x = x + 8) {
322 : Isibaar 579 interpolate8x8_6tap_lowpass_v(hv_ptr, h_ptr, edged_width, rounding);
323 :     hv_ptr += 8;
324 :     h_ptr += 8;
325 :     }
326 : Isibaar 586
327 : syskin 681 hv_ptr += EDGE_SIZE;
328 :     h_ptr += EDGE_SIZE;
329 : Isibaar 586
330 : Isibaar 579 hv_ptr += stride_add;
331 :     h_ptr += stride_add;
332 :     }
333 : albeu 315 }
334 : Isibaar 579 else {
335 :    
336 : Isibaar 586 for (y = 0; y < (edged_height - EDGE_SIZE); y += 8) {
337 :     for (x = 0; x < (edged_width - EDGE_SIZE); x += 8) {
338 : Isibaar 579 interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);
339 :     interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);
340 :     interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);
341 :    
342 :     n_ptr += 8;
343 :     h_ptr += 8;
344 :     v_ptr += 8;
345 :     hv_ptr += 8;
346 :     }
347 :    
348 : Isibaar 586 h_ptr += EDGE_SIZE;
349 :     v_ptr += EDGE_SIZE;
350 :     hv_ptr += EDGE_SIZE;
351 :     n_ptr += EDGE_SIZE;
352 :    
353 : Isibaar 579 h_ptr += stride_add;
354 :     v_ptr += stride_add;
355 :     hv_ptr += stride_add;
356 :     n_ptr += stride_add;
357 :     }
358 :     }
359 : chl 530 /*
360 :     #ifdef BFRAMES
361 : albeu 315 n_ptr = refn->u;
362 :     h_ptr = refh->u;
363 :     v_ptr = refv->u;
364 :     hv_ptr = refhv->u;
365 :    
366 :     n_ptr -= offset2;
367 :     h_ptr -= offset2;
368 :     v_ptr -= offset2;
369 :     hv_ptr -= offset2;
370 :    
371 : chl 530 for (y = 0; y < edged_height2; y += 8) {
372 :     for (x = 0; x < edged_width2; x += 8) {
373 : albeu 315 interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);
374 :     interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);
375 :     interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);
376 :    
377 :     n_ptr += 8;
378 :     h_ptr += 8;
379 :     v_ptr += 8;
380 :     hv_ptr += 8;
381 :     }
382 :     h_ptr += stride_add2;
383 :     v_ptr += stride_add2;
384 :     hv_ptr += stride_add2;
385 :     n_ptr += stride_add2;
386 :     }
387 :    
388 :     n_ptr = refn->v;
389 :     h_ptr = refh->v;
390 :     v_ptr = refv->v;
391 :     hv_ptr = refhv->v;
392 :    
393 :     n_ptr -= offset2;
394 :     h_ptr -= offset2;
395 :     v_ptr -= offset2;
396 :     hv_ptr -= offset2;
397 :    
398 :     for (y = 0; y < edged_height2; y = y + 8) {
399 :     for (x = 0; x < edged_width2; x = x + 8) {
400 :     interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width2, rounding);
401 :     interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width2, rounding);
402 :     interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width2, rounding);
403 :    
404 :     n_ptr += 8;
405 :     h_ptr += 8;
406 :     v_ptr += 8;
407 :     hv_ptr += 8;
408 :     }
409 :     h_ptr += stride_add2;
410 :     v_ptr += stride_add2;
411 :     hv_ptr += stride_add2;
412 :     n_ptr += stride_add2;
413 :     }
414 : chl 530 #endif
415 : suxen_drol 449 */
416 : chl 530 /*
417 :     interpolate_halfpel_h(
418 :     refh->y - offset,
419 :     refn->y - offset,
420 :     edged_width, edged_height,
421 :     rounding);
422 :    
423 :     interpolate_halfpel_v(
424 :     refv->y - offset,
425 :     refn->y - offset,
426 :     edged_width, edged_height,
427 :     rounding);
428 :    
429 :     interpolate_halfpel_hv(
430 :     refhv->y - offset,
431 :     refn->y - offset,
432 :     edged_width, edged_height,
433 :     rounding);
434 :     */
435 :    
436 :     /* uv-image-based compensation
437 :     offset = EDGE_SIZE2 * (edged_width / 2 + 1);
438 :    
439 :     interpolate_halfpel_h(
440 :     refh->u - offset,
441 :     refn->u - offset,
442 :     edged_width / 2, edged_height / 2,
443 :     rounding);
444 :    
445 :     interpolate_halfpel_v(
446 :     refv->u - offset,
447 :     refn->u - offset,
448 :     edged_width / 2, edged_height / 2,
449 :     rounding);
450 :    
451 :     interpolate_halfpel_hv(
452 :     refhv->u - offset,
453 :     refn->u - offset,
454 :     edged_width / 2, edged_height / 2,
455 :     rounding);
456 :    
457 :    
458 :     interpolate_halfpel_h(
459 :     refh->v - offset,
460 :     refn->v - offset,
461 :     edged_width / 2, edged_height / 2,
462 :     rounding);
463 :    
464 :     interpolate_halfpel_v(
465 :     refv->v - offset,
466 :     refn->v - offset,
467 :     edged_width / 2, edged_height / 2,
468 :     rounding);
469 :    
470 :     interpolate_halfpel_hv(
471 :     refhv->v - offset,
472 :     refn->v - offset,
473 :     edged_width / 2, edged_height / 2,
474 :     rounding);
475 :     */
476 : albeu 315 }
477 :    
478 :    
479 : suxen_drol 708 /*
480 :     chroma optimize filter, invented by mf
481 :     a chroma pixel is average from the surrounding pixels, when the
482 :     correpsonding luma pixels are pure black or white.
483 :     */
484 : suxen_drol 631
485 : suxen_drol 708 void
486 :     image_chroma_optimize(IMAGE * img, int width, int height, int edged_width)
487 :     {
488 :     int x,y;
489 :     int pixels = 0;
490 :    
491 :     for (y = 1; y < height/2 - 1; y++)
492 :     for (x = 1; x < width/2 - 1; x++)
493 :     {
494 :     #define IS_PURE(a) ((a)<=16||(a)>=235)
495 :     #define IMG_Y(Y,X) img->y[(Y)*edged_width + (X)]
496 :     #define IMG_U(Y,X) img->u[(Y)*edged_width/2 + (X)]
497 :     #define IMG_V(Y,X) img->v[(Y)*edged_width/2 + (X)]
498 :    
499 :     if (IS_PURE(IMG_Y(y*2 ,x*2 )) &&
500 :     IS_PURE(IMG_Y(y*2 ,x*2+1)) &&
501 :     IS_PURE(IMG_Y(y*2+1,x*2 )) &&
502 :     IS_PURE(IMG_Y(y*2+1,x*2+1)))
503 :     {
504 :     IMG_U(y,x) = (IMG_U(y,x-1) + IMG_U(y-1, x) + IMG_U(y, x+1) + IMG_U(y+1, x)) / 4;
505 :     IMG_V(y,x) = (IMG_V(y,x-1) + IMG_V(y-1, x) + IMG_V(y, x+1) + IMG_V(y+1, x)) / 4;
506 :     pixels++;
507 :     }
508 :    
509 :     #undef IS_PURE
510 :     #undef IMG_Y
511 :     #undef IMG_U
512 :     #undef IMG_V
513 :     }
514 :    
515 :     DPRINTF(DPRINTF_DEBUG,"chroma_optimized_pixels = %i/%i", pixels, width*height/4);
516 :     }
517 :    
518 :    
519 :    
520 :    
521 :    
522 : suxen_drol 631 /*
523 :     perform safe packed colorspace conversion, by splitting
524 :     the image up into an optimized area (pixel width divisible by 16),
525 :     and two unoptimized/plain-c areas (pixel width divisible by 2)
526 :     */
527 :    
528 :     static void
529 :     safe_packed_conv(uint8_t * x_ptr, int x_stride,
530 :     uint8_t * y_ptr, uint8_t * u_ptr, uint8_t * v_ptr,
531 :     int y_stride, int uv_stride,
532 :     int width, int height, int vflip,
533 :     packedFunc * func_opt, packedFunc func_c, int size)
534 :     {
535 :     int width_opt, width_c;
536 :    
537 :     if (func_opt != func_c && x_stride < size*((width+15)/16)*16)
538 :     {
539 :     width_opt = width & (~15);
540 :     width_c = width - width_opt;
541 :     }
542 :     else
543 :     {
544 :     width_opt = width;
545 :     width_c = 0;
546 :     }
547 :    
548 :     func_opt(x_ptr, x_stride,
549 :     y_ptr, u_ptr, v_ptr, y_stride, uv_stride,
550 :     width_opt, height, vflip);
551 :    
552 :     if (width_c)
553 :     {
554 :     func_c(x_ptr + size*width_opt, x_stride,
555 :     y_ptr + width_opt, u_ptr + width_opt/2, v_ptr + width_opt/2,
556 :     y_stride, uv_stride, width_c, height, vflip);
557 :     }
558 :     }
559 :    
560 :    
561 :    
562 : albeu 315 int
563 :     image_input(IMAGE * image,
564 :     uint32_t width,
565 :     int height,
566 :     uint32_t edged_width,
567 :     uint8_t * src,
568 : suxen_drol 631 int src_stride,
569 :     int csp,
570 :     int interlacing)
571 : albeu 315 {
572 : suxen_drol 631 const int edged_width2 = edged_width/2;
573 :     const int width2 = width/2;
574 :     const int height2 = height/2;
575 :     //const int height_signed = (csp & XVID_CSP_VFLIP) ? -height : height;
576 : albeu 315
577 : suxen_drol 631
578 :     // int src_stride = width;
579 :    
580 :     // --- xvid 2.1 compatiblity patch ---
581 :     // --- remove when xvid_dec_frame->stride equals real stride
582 :     /*
583 :     if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 ||
584 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 ||
585 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 ||
586 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU ||
587 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY)
588 : albeu 315 {
589 : suxen_drol 631 src_stride *= 2;
590 :     }
591 :     else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)
592 :     {
593 :     src_stride *= 3;
594 : albeu 315 }
595 : suxen_drol 631 else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||
596 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||
597 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)
598 :     {
599 :     src_stride *= 4;
600 :     }
601 :     */
602 :     // ^--- xvid 2.1 compatiblity fix ---^
603 : albeu 315
604 :     switch (csp & ~XVID_CSP_VFLIP) {
605 :     case XVID_CSP_RGB555:
606 : suxen_drol 631 safe_packed_conv(
607 :     src, src_stride, image->y, image->u, image->v,
608 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
609 :     interlacing?rgb555i_to_yv12 :rgb555_to_yv12,
610 :     interlacing?rgb555i_to_yv12_c:rgb555_to_yv12_c, 2);
611 :     break;
612 : albeu 315
613 :     case XVID_CSP_RGB565:
614 : suxen_drol 631 safe_packed_conv(
615 :     src, src_stride, image->y, image->u, image->v,
616 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
617 :     interlacing?rgb565i_to_yv12 :rgb565_to_yv12,
618 :     interlacing?rgb565i_to_yv12_c:rgb565_to_yv12_c, 2);
619 :     break;
620 : albeu 315
621 :    
622 :     case XVID_CSP_RGB24:
623 : suxen_drol 631 safe_packed_conv(
624 :     src, src_stride, image->y, image->u, image->v,
625 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
626 :     interlacing?bgri_to_yv12 :bgr_to_yv12,
627 :     interlacing?bgri_to_yv12_c:bgr_to_yv12_c, 3);
628 :     break;
629 : albeu 315
630 :     case XVID_CSP_RGB32:
631 : suxen_drol 631 safe_packed_conv(
632 :     src, src_stride, image->y, image->u, image->v,
633 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
634 :     interlacing?bgrai_to_yv12 :bgra_to_yv12,
635 :     interlacing?bgrai_to_yv12_c:bgra_to_yv12_c, 4);
636 :     break;
637 : albeu 315
638 : suxen_drol 631 case XVID_CSP_ABGR :
639 :     safe_packed_conv(
640 :     src, src_stride, image->y, image->u, image->v,
641 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
642 :     interlacing?abgri_to_yv12 :abgr_to_yv12,
643 :     interlacing?abgri_to_yv12_c:abgr_to_yv12_c, 4);
644 :     break;
645 : albeu 315
646 : suxen_drol 631 case XVID_CSP_RGBA :
647 :     safe_packed_conv(
648 :     src, src_stride, image->y, image->u, image->v,
649 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
650 :     interlacing?rgbai_to_yv12 :rgba_to_yv12,
651 :     interlacing?rgbai_to_yv12_c:rgba_to_yv12_c, 4);
652 :     break;
653 : albeu 315
654 :     case XVID_CSP_YUY2:
655 : suxen_drol 631 safe_packed_conv(
656 :     src, src_stride, image->y, image->u, image->v,
657 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
658 :     interlacing?yuyvi_to_yv12 :yuyv_to_yv12,
659 :     interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2);
660 :     break;
661 : albeu 315
662 :     case XVID_CSP_YVYU: /* u/v swapped */
663 : suxen_drol 631 safe_packed_conv(
664 :     src, src_stride, image->y, image->v, image->y,
665 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
666 :     interlacing?yuyvi_to_yv12 :yuyv_to_yv12,
667 :     interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2);
668 :     break;
669 : albeu 315
670 :     case XVID_CSP_UYVY:
671 : suxen_drol 631 safe_packed_conv(
672 :     src, src_stride, image->y, image->u, image->v,
673 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
674 :     interlacing?uyvyi_to_yv12 :uyvy_to_yv12,
675 :     interlacing?uyvyi_to_yv12_c:uyvy_to_yv12_c, 2);
676 :     break;
677 : albeu 315
678 : suxen_drol 631 case XVID_CSP_I420:
679 :     yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2,
680 : suxen_drol 726 src, src + src_stride*height, src + src_stride*height + (src_stride/2)*height2,
681 :     src_stride, src_stride/2, width, height, (csp & XVID_CSP_VFLIP));
682 : suxen_drol 631 break
683 :     ;
684 :     case XVID_CSP_YV12: /* u/v swapped */
685 :     yv12_to_yv12(image->y, image->v, image->u, edged_width, edged_width2,
686 : suxen_drol 726 src, src + src_stride*height, src + src_stride*height + (src_stride/2)*height2,
687 :     src_stride, src_stride/2, width, height, (csp & XVID_CSP_VFLIP));
688 : suxen_drol 631 break;
689 :    
690 : albeu 315 case XVID_CSP_USER:
691 : suxen_drol 631 {
692 :     DEC_PICTURE * pic = (DEC_PICTURE*)src;
693 :     yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2,
694 :     pic->y, pic->u, pic->v, pic->stride_y, pic->stride_y,
695 :     width, height, (csp & XVID_CSP_VFLIP));
696 :     }
697 :     break;
698 : albeu 315
699 :     case XVID_CSP_NULL:
700 :     break;
701 :    
702 : suxen_drol 631 default :
703 :     return -1;
704 : albeu 315 }
705 :    
706 : suxen_drol 631
707 :     /* pad out image when the width and/or height is not a multiple of 16 */
708 :    
709 :     if (width & 15)
710 :     {
711 :     int i;
712 :     int pad_width = 16 - (width&15);
713 :     for (i = 0; i < height; i++)
714 :     {
715 :     memset(image->y + i*edged_width + width,
716 :     *(image->y + i*edged_width + width - 1), pad_width);
717 :     }
718 :     for (i = 0; i < height/2; i++)
719 :     {
720 :     memset(image->u + i*edged_width2 + width2,
721 :     *(image->u + i*edged_width2 + width2 - 1),pad_width/2);
722 :     memset(image->v + i*edged_width2 + width2,
723 :     *(image->v + i*edged_width2 + width2 - 1),pad_width/2);
724 :     }
725 :     }
726 :    
727 :     if (height & 15)
728 :     {
729 :     int pad_height = 16 - (height&15);
730 :     int length = ((width+15)/16)*16;
731 :     int i;
732 :     for (i = 0; i < pad_height; i++)
733 :     {
734 :     memcpy(image->y + (height+i)*edged_width,
735 :     image->y + (height-1)*edged_width,length);
736 :     }
737 :    
738 :     for (i = 0; i < pad_height/2; i++)
739 :     {
740 :     memcpy(image->u + (height2+i)*edged_width2,
741 :     image->u + (height2-1)*edged_width2,length/2);
742 :     memcpy(image->v + (height2+i)*edged_width2,
743 :     image->v + (height2-1)*edged_width2,length/2);
744 :     }
745 :     }
746 :    
747 :     /*
748 :     if (interlacing)
749 :     image_printf(image, edged_width, height, 5,5, "[i]");
750 :     image_dump_yuvpgm(image, edged_width, ((width+15)/16)*16, ((height+15)/16)*16, "\\encode.pgm");
751 :     */
752 :     return 0;
753 : albeu 315 }
754 :    
755 :    
756 :    
757 :     int
758 :     image_output(IMAGE * image,
759 :     uint32_t width,
760 :     int height,
761 :     uint32_t edged_width,
762 :     uint8_t * dst,
763 :     uint32_t dst_stride,
764 : suxen_drol 631 int csp,
765 :     int interlacing)
766 : albeu 315 {
767 : suxen_drol 631 const int edged_width2 = edged_width/2;
768 :     int height2 = height/2;
769 : albeu 315
770 : suxen_drol 631 /*
771 :     if (interlacing)
772 :     image_printf(image, edged_width, height, 5,100, "[i]=%i,%i",width,height);
773 :     image_dump_yuvpgm(image, edged_width, width, height, "\\decode.pgm");
774 :     */
775 :    
776 :    
777 : suxen_drol 582 // --- xvid 2.1 compatiblity patch ---
778 :     // --- remove when xvid_dec_frame->stride equals real stride
779 : suxen_drol 631 /*
780 : suxen_drol 582 if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB555 ||
781 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB565 ||
782 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YUY2 ||
783 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_YVYU ||
784 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_UYVY)
785 :     {
786 :     dst_stride *= 2;
787 :     }
788 :     else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB24)
789 :     {
790 :     dst_stride *= 3;
791 :     }
792 :     else if ((csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGB32 ||
793 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_ABGR ||
794 :     (csp & ~XVID_CSP_VFLIP) == XVID_CSP_RGBA)
795 :     {
796 :     dst_stride *= 4;
797 :     }
798 : suxen_drol 631 */
799 : suxen_drol 582 // ^--- xvid 2.1 compatiblity fix ---^
800 :    
801 :    
802 : albeu 315 switch (csp & ~XVID_CSP_VFLIP) {
803 :     case XVID_CSP_RGB555:
804 : suxen_drol 631 safe_packed_conv(
805 :     dst, dst_stride, image->y, image->u, image->v,
806 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
807 :     interlacing?yv12_to_rgb555i :yv12_to_rgb555,
808 :     interlacing?yv12_to_rgb555i_c:yv12_to_rgb555_c, 2);
809 : albeu 315 return 0;
810 :    
811 :     case XVID_CSP_RGB565:
812 : suxen_drol 631 safe_packed_conv(
813 :     dst, dst_stride, image->y, image->u, image->v,
814 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
815 :     interlacing?yv12_to_rgb565i :yv12_to_rgb565,
816 :     interlacing?yv12_to_rgb565i_c:yv12_to_rgb565_c, 2);
817 : albeu 315 return 0;
818 :    
819 :     case XVID_CSP_RGB24:
820 : suxen_drol 631 safe_packed_conv(
821 :     dst, dst_stride, image->y, image->u, image->v,
822 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
823 :     interlacing?yv12_to_bgri :yv12_to_bgr,
824 :     interlacing?yv12_to_bgri_c:yv12_to_bgr_c, 3);
825 : albeu 315 return 0;
826 :    
827 :     case XVID_CSP_RGB32:
828 : suxen_drol 631 safe_packed_conv(
829 :     dst, dst_stride, image->y, image->u, image->v,
830 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
831 :     interlacing?yv12_to_bgrai :yv12_to_bgra,
832 :     interlacing?yv12_to_bgrai_c:yv12_to_bgra_c, 4);
833 : albeu 315 return 0;
834 :    
835 : suxen_drol 582 case XVID_CSP_ABGR:
836 : suxen_drol 631 safe_packed_conv(
837 :     dst, dst_stride, image->y, image->u, image->v,
838 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
839 :     interlacing?yv12_to_abgri :yv12_to_abgr,
840 :     interlacing?yv12_to_abgri_c:yv12_to_abgr_c, 4);
841 : suxen_drol 582 return 0;
842 :    
843 :     case XVID_CSP_RGBA:
844 : suxen_drol 631 safe_packed_conv(
845 :     dst, dst_stride, image->y, image->u, image->v,
846 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
847 :     interlacing?yv12_to_rgbai :yv12_to_rgba,
848 :     interlacing?yv12_to_rgbai_c:yv12_to_rgba_c, 4);
849 : suxen_drol 582 return 0;
850 :    
851 : suxen_drol 631 case XVID_CSP_YUY2:
852 :     safe_packed_conv(
853 :     dst, dst_stride, image->y, image->u, image->v,
854 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
855 :     interlacing?yv12_to_yuyvi :yv12_to_yuyv,
856 :     interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2);
857 : albeu 315 return 0;
858 :    
859 : suxen_drol 631 case XVID_CSP_YVYU: // u,v swapped
860 :     safe_packed_conv(
861 :     dst, dst_stride, image->y, image->v, image->u,
862 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
863 :     interlacing?yv12_to_yuyvi :yv12_to_yuyv,
864 :     interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2);
865 : albeu 315 return 0;
866 :    
867 : suxen_drol 631 case XVID_CSP_UYVY:
868 :     safe_packed_conv(
869 :     dst, dst_stride, image->y, image->u, image->v,
870 :     edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP),
871 :     interlacing?yv12_to_uyvyi :yv12_to_uyvy,
872 :     interlacing?yv12_to_uyvyi_c:yv12_to_uyvy_c, 2);
873 : albeu 315 return 0;
874 :    
875 : suxen_drol 631 case XVID_CSP_I420:
876 : suxen_drol 726 yv12_to_yv12(dst, dst + dst_stride*height, dst + dst_stride*height + (dst_stride/2)*height2,
877 :     dst_stride, dst_stride/2,
878 : suxen_drol 631 image->y, image->u, image->v, edged_width, edged_width2,
879 :     width, height, (csp & XVID_CSP_VFLIP));
880 : albeu 315 return 0;
881 :    
882 : suxen_drol 631 case XVID_CSP_YV12: // u,v swapped
883 : suxen_drol 726 yv12_to_yv12(dst, dst + dst_stride*height, dst + dst_stride*height + (dst_stride/2)*height2,
884 :     dst_stride, dst_stride/2,
885 : suxen_drol 631 image->y, image->v, image->u, edged_width, edged_width2,
886 :     width, height, (csp & XVID_CSP_VFLIP));
887 : albeu 315 return 0;
888 :    
889 :     case XVID_CSP_USER:
890 : suxen_drol 631 {
891 :     DEC_PICTURE * pic = (DEC_PICTURE*)dst;
892 :     pic->y = image->y;
893 :     pic->u = image->u;
894 :     pic->v = image->v;
895 :     pic->stride_y = edged_width;
896 :     pic->stride_uv = edged_width / 2;
897 :     }
898 : albeu 315 return 0;
899 :    
900 :     case XVID_CSP_NULL:
901 :     case XVID_CSP_EXTERN:
902 :     return 0;
903 :    
904 :     }
905 :    
906 :     return -1;
907 :     }
908 :    
909 :     float
910 :     image_psnr(IMAGE * orig_image,
911 :     IMAGE * recon_image,
912 :     uint16_t stride,
913 :     uint16_t width,
914 :     uint16_t height)
915 :     {
916 :     int32_t diff, x, y, quad = 0;
917 :     uint8_t *orig = orig_image->y;
918 :     uint8_t *recon = recon_image->y;
919 :     float psnr_y;
920 :    
921 :     for (y = 0; y < height; y++) {
922 :     for (x = 0; x < width; x++) {
923 :     diff = *(orig + x) - *(recon + x);
924 :     quad += diff * diff;
925 :     }
926 :     orig += stride;
927 :     recon += stride;
928 :     }
929 :    
930 :     psnr_y = (float) quad / (float) (width * height);
931 :    
932 :     if (psnr_y) {
933 :     psnr_y = (float) (255 * 255) / psnr_y;
934 :     psnr_y = 10 * (float) log10(psnr_y);
935 :     } else
936 :     psnr_y = (float) 99.99;
937 :    
938 :     return psnr_y;
939 :     }
940 :    
941 : chl 807 long plane_sse(uint8_t * orig,
942 :     uint8_t * recon,
943 :     uint16_t stride,
944 :     uint16_t width,
945 :     uint16_t height)
946 :     {
947 :     int diff, x, y;
948 :     long sse=0;
949 :    
950 :     for (y = 0; y < height; y++) {
951 :     for (x = 0; x < width; x++) {
952 :     diff = *(orig + x) - *(recon + x);
953 :     sse += diff * diff;
954 :     }
955 :     orig += stride;
956 :     recon += stride;
957 :     }
958 :     return sse;
959 :     }
960 :    
961 : albeu 315 /*
962 :    
963 :     #include <stdio.h>
964 :     #include <string.h>
965 :    
966 :     int image_dump_pgm(uint8_t * bmp, uint32_t width, uint32_t height, char * filename)
967 :     {
968 :     FILE * f;
969 :     char hdr[1024];
970 :    
971 :     f = fopen(filename, "wb");
972 :     if ( f == NULL)
973 :     {
974 :     return -1;
975 :     }
976 :     sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, height);
977 :     fwrite(hdr, strlen(hdr), 1, f);
978 :     fwrite(bmp, width, height, f);
979 :     fclose(f);
980 :    
981 :     return 0;
982 :     }
983 :    
984 :    
985 :     // dump image+edges to yuv pgm files
986 :    
987 :     int image_dump(IMAGE * image, uint32_t edged_width, uint32_t edged_height, char * path, int number)
988 :     {
989 :     char filename[1024];
990 :    
991 :     sprintf(filename, "%s_%i_%c.pgm", path, number, 'y');
992 :     image_dump_pgm(
993 :     image->y - (EDGE_SIZE * edged_width + EDGE_SIZE),
994 :     edged_width, edged_height, filename);
995 :    
996 :     sprintf(filename, "%s_%i_%c.pgm", path, number, 'u');
997 :     image_dump_pgm(
998 :     image->u - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2),
999 :     edged_width / 2, edged_height / 2, filename);
1000 :    
1001 :     sprintf(filename, "%s_%i_%c.pgm", path, number, 'v');
1002 :     image_dump_pgm(
1003 :     image->v - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2),
1004 :     edged_width / 2, edged_height / 2, filename);
1005 :    
1006 :     return 0;
1007 :     }
1008 :     */
1009 :    
1010 :    
1011 :    
1012 :     /* dump image to yuvpgm file */
1013 :    
1014 :     #include <stdio.h>
1015 :    
1016 :     int
1017 :     image_dump_yuvpgm(const IMAGE * image,
1018 :     const uint32_t edged_width,
1019 :     const uint32_t width,
1020 :     const uint32_t height,
1021 :     char *filename)
1022 :     {
1023 :     FILE *f;
1024 :     char hdr[1024];
1025 :     uint32_t i;
1026 :     uint8_t *bmp1;
1027 :     uint8_t *bmp2;
1028 :    
1029 :    
1030 :     f = fopen(filename, "wb");
1031 :     if (f == NULL) {
1032 :     return -1;
1033 :     }
1034 :     sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, (3 * height) / 2);
1035 :     fwrite(hdr, strlen(hdr), 1, f);
1036 :    
1037 :     bmp1 = image->y;
1038 :     for (i = 0; i < height; i++) {
1039 :     fwrite(bmp1, width, 1, f);
1040 :     bmp1 += edged_width;
1041 :     }
1042 :    
1043 :     bmp1 = image->u;
1044 :     bmp2 = image->v;
1045 :     for (i = 0; i < height / 2; i++) {
1046 :     fwrite(bmp1, width / 2, 1, f);
1047 :     fwrite(bmp2, width / 2, 1, f);
1048 :     bmp1 += edged_width / 2;
1049 :     bmp2 += edged_width / 2;
1050 :     }
1051 :    
1052 :     fclose(f);
1053 :     return 0;
1054 :     }
1055 :    
1056 :    
1057 :     float
1058 :     image_mad(const IMAGE * img1,
1059 :     const IMAGE * img2,
1060 :     uint32_t stride,
1061 :     uint32_t width,
1062 :     uint32_t height)
1063 :     {
1064 :     const uint32_t stride2 = stride / 2;
1065 :     const uint32_t width2 = width / 2;
1066 :     const uint32_t height2 = height / 2;
1067 :    
1068 :     uint32_t x, y;
1069 :     uint32_t sum = 0;
1070 :    
1071 :     for (y = 0; y < height; y++)
1072 :     for (x = 0; x < width; x++)
1073 :     sum += ABS(img1->y[x + y * stride] - img2->y[x + y * stride]);
1074 :    
1075 :     for (y = 0; y < height2; y++)
1076 :     for (x = 0; x < width2; x++)
1077 :     sum += ABS(img1->u[x + y * stride2] - img2->u[x + y * stride2]);
1078 :    
1079 :     for (y = 0; y < height2; y++)
1080 :     for (x = 0; x < width2; x++)
1081 :     sum += ABS(img1->v[x + y * stride2] - img2->v[x + y * stride2]);
1082 :    
1083 :     return (float) sum / (width * height * 3 / 2);
1084 :     }
1085 :    
1086 :     void
1087 :     output_slice(IMAGE * cur, int std, int width, XVID_DEC_PICTURE* out_frm, int mbx, int mby,int mbl) {
1088 :     uint8_t *dY,*dU,*dV,*sY,*sU,*sV;
1089 :     int std2 = std >> 1;
1090 :     int w = mbl << 4, w2,i;
1091 :    
1092 :     if(w > width)
1093 :     w = width;
1094 :     w2 = w >> 1;
1095 : suxen_drol 323
1096 : albeu 315 dY = (uint8_t*)out_frm->y + (mby << 4) * out_frm->stride_y + (mbx << 4);
1097 :     dU = (uint8_t*)out_frm->u + (mby << 3) * out_frm->stride_u + (mbx << 3);
1098 :     dV = (uint8_t*)out_frm->v + (mby << 3) * out_frm->stride_v + (mbx << 3);
1099 :     sY = cur->y + (mby << 4) * std + (mbx << 4);
1100 :     sU = cur->u + (mby << 3) * std2 + (mbx << 3);
1101 :     sV = cur->v + (mby << 3) * std2 + (mbx << 3);
1102 :    
1103 :     for(i = 0 ; i < 16 ; i++) {
1104 :     memcpy(dY,sY,w);
1105 : suxen_drol 323 dY += out_frm->stride_y;
1106 :     sY += std;
1107 :     }
1108 : albeu 315 for(i = 0 ; i < 8 ; i++) {
1109 :     memcpy(dU,sU,w2);
1110 :     dU += out_frm->stride_u;
1111 :     sU += std2;
1112 :     }
1113 :     for(i = 0 ; i < 8 ; i++) {
1114 :     memcpy(dV,sV,w2);
1115 :     dV += out_frm->stride_v;
1116 :     sV += std2;
1117 :     }
1118 :     }
1119 : suxen_drol 702
1120 :    
1121 :     void
1122 : suxen_drol 715 image_clear(IMAGE * img, int width, int height, int edged_width,
1123 :     int y, int u, int v)
1124 :     {
1125 :     uint8_t * p;
1126 :     int i;
1127 :    
1128 :     p = img->y;
1129 :     for (i = 0; i < height; i++) {
1130 :     memset(p, y, width);
1131 :     p += edged_width;
1132 :     }
1133 :    
1134 :     p = img->u;
1135 :     for (i = 0; i < height/2; i++) {
1136 :     memset(p, u, width/2);
1137 :     p += edged_width/2;
1138 :     }
1139 :    
1140 :     p = img->v;
1141 :     for (i = 0; i < height/2; i++) {
1142 :     memset(p, v, width/2);
1143 :     p += edged_width/2;
1144 :     }
1145 :     }
1146 :    
1147 :    
1148 :     /* reduced resolution deblocking filter
1149 :     block = block size (16=rrv, 8=full resolution)
1150 :     flags = XVID_DEC_YDEBLOCK|XVID_DEC_UVDEBLOCK
1151 :     */
1152 :     void
1153 : suxen_drol 702 image_deblock_rrv(IMAGE * img, int edged_width,
1154 : suxen_drol 715 const MACROBLOCK * mbs, int mb_width, int mb_height, int mb_stride,
1155 :     int block, int flags)
1156 : suxen_drol 702 {
1157 :     const int edged_width2 = edged_width /2;
1158 : suxen_drol 715 const int nblocks = block / 8; /* skals code uses 8pixel block uints */
1159 : suxen_drol 702 int i,j;
1160 :    
1161 : suxen_drol 715 /* luma: j,i in block units */
1162 :     if ((flags & XVID_DEC_DEBLOCKY))
1163 : suxen_drol 702 {
1164 : suxen_drol 715 for (j = 1; j < mb_height*2; j++) /* horizontal deblocking */
1165 :     for (i = 0; i < mb_width*2; i++)
1166 : suxen_drol 702 {
1167 : suxen_drol 715 if (mbs[(j-1)/2*mb_stride + (i/2)].mode != MODE_NOT_CODED ||
1168 :     mbs[(j+0)/2*mb_stride + (i/2)].mode != MODE_NOT_CODED)
1169 :     {
1170 : suxen_drol 747 hfilter_31(img->y + (j*block - 1)*edged_width + i*block,
1171 : suxen_drol 715 img->y + (j*block + 0)*edged_width + i*block, nblocks);
1172 :     }
1173 : suxen_drol 702 }
1174 :    
1175 : suxen_drol 715 for (j = 0; j < mb_height*2; j++) /* vertical deblocking */
1176 :     for (i = 1; i < mb_width*2; i++)
1177 : suxen_drol 702 {
1178 : suxen_drol 715 if (mbs[(j/2)*mb_stride + (i-1)/2].mode != MODE_NOT_CODED ||
1179 :     mbs[(j/2)*mb_stride + (i+0)/2].mode != MODE_NOT_CODED)
1180 :     {
1181 :     vfilter_31(img->y + (j*block)*edged_width + i*block - 1,
1182 :     img->y + (j*block)*edged_width + i*block + 0,
1183 :     edged_width, nblocks);
1184 :     }
1185 : suxen_drol 702 }
1186 :     }
1187 :    
1188 :    
1189 : suxen_drol 715 /* chroma */
1190 :     if ((flags & XVID_DEC_DEBLOCKUV))
1191 : suxen_drol 702 {
1192 : suxen_drol 747 for (j = 1; j < mb_height; j++) /* horizontal deblocking */
1193 :     for (i = 0; i < mb_width; i++)
1194 :     {
1195 :     if (mbs[(j-1)*mb_stride + i].mode != MODE_NOT_CODED ||
1196 :     mbs[(j+0)*mb_stride + i].mode != MODE_NOT_CODED)
1197 :     {
1198 :     hfilter_31(img->u + (j*block - 1)*edged_width2 + i*block,
1199 :     img->u + (j*block + 0)*edged_width2 + i*block, nblocks);
1200 :     hfilter_31(img->v + (j*block - 1)*edged_width2 + i*block,
1201 :     img->v + (j*block + 0)*edged_width2 + i*block, nblocks);
1202 :     }
1203 :     }
1204 :    
1205 :     for (j = 0; j < mb_height; j++) /* vertical deblocking */
1206 : suxen_drol 715 for (i = 1; i < mb_width; i++)
1207 : suxen_drol 702 {
1208 : suxen_drol 715 if (mbs[j*mb_stride + i - 1].mode != MODE_NOT_CODED ||
1209 :     mbs[j*mb_stride + i + 0].mode != MODE_NOT_CODED)
1210 :     {
1211 :     vfilter_31(img->u + (j*block)*edged_width2 + i*block - 1,
1212 :     img->u + (j*block)*edged_width2 + i*block + 0,
1213 :     edged_width2, nblocks);
1214 :     vfilter_31(img->v + (j*block)*edged_width2 + i*block - 1,
1215 :     img->v + (j*block)*edged_width2 + i*block + 0,
1216 :     edged_width2, nblocks);
1217 :     }
1218 : suxen_drol 702 }
1219 :     }
1220 : suxen_drol 715
1221 : suxen_drol 702 }
1222 : chl 769

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4