[svn] / branches / release-1_3-branch / xvidcore / src / image / image.c Repository:
ViewVC logotype

Annotation of /branches/release-1_3-branch/xvidcore/src/image/image.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 677 - (view) (download)
Original Path: trunk/xvidcore/src/image/image.c

1 : chl 433 /*****************************************************************************
2 : albeu 315 *
3 : chl 433 * XVID MPEG-4 VIDEO CODEC
4 :     * - image module -
5 : albeu 315 *
6 : chl 433 * Copyright(C) 2002 Peter Ross <pross@xvid.org>
7 : albeu 315 *
8 : edgomez 651 * This file is part of XviD, a free MPEG-4 video encoder/decoder
9 : albeu 315 *
10 : edgomez 651 * XviD is free software; you can redistribute it and/or modify it
11 :     * under the terms of the GNU General Public License as published by
12 : chl 433 * the Free Software Foundation; either version 2 of the License, or
13 :     * (at your option) any later version.
14 : albeu 315 *
15 : chl 433 * This program is distributed in the hope that it will be useful,
16 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 :     * GNU General Public License for more details.
19 : albeu 315 *
20 : chl 433 * You should have received a copy of the GNU General Public License
21 :     * along with this program; if not, write to the Free Software
22 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 : albeu 315 *
24 : edgomez 651 * Under section 8 of the GNU General Public License, the copyright
25 :     * holders of XVID explicitly forbid distribution in the following
26 :     * countries:
27 :     *
28 :     * - Japan
29 :     * - United States of America
30 :     *
31 :     * Linking XviD statically or dynamically with other modules is making a
32 :     * combined work based on XviD. Thus, the terms and conditions of the
33 :     * GNU General Public License cover the whole combination.
34 :     *
35 :     * As a special exception, the copyright holders of XviD give you
36 :     * permission to link XviD with independent modules that communicate with
37 :     * XviD solely through the VFW1.1 and DShow interfaces, regardless of the
38 :     * license terms of these independent modules, and to copy and distribute
39 :     * the resulting combined work under terms of your choice, provided that
40 :     * every copy of the combined work is accompanied by a complete copy of
41 :     * the source code of XviD (the version of XviD used to produce the
42 :     * combined work), being distributed under the terms of the GNU General
43 :     * Public License plus this exception. An independent module is a module
44 :     * which is not derived from or based on XviD.
45 :     *
46 :     * Note that people who make modified versions of XviD are not obligated
47 :     * to grant this special exception for their modified versions; it is
48 :     * their choice whether to do so. The GNU General Public License gives
49 :     * permission to release a modified version without this exception; this
50 :     * exception also makes it possible to release a modified version which
51 :     * carries forward this exception.
52 :     *
53 : edgomez 677 * $Id: image.c,v 1.25 2002-11-26 23:44:10 edgomez Exp $
54 : edgomez 651 *
55 : chl 433 ****************************************************************************/
56 : albeu 315
57 :     #include <stdlib.h>
58 : edgomez 677 #include <string.h> /* memcpy, memset */
59 : albeu 315 #include <math.h>
60 :    
61 :     #include "../portab.h"
62 : edgomez 677 #include "../xvid.h"
63 : albeu 315 #include "image.h"
64 :     #include "colorspace.h"
65 :     #include "interpolate8x8.h"
66 :     #include "../divx4.h"
67 :     #include "../utils/mem_align.h"
68 :    
69 :     #define SAFETY 64
70 :     #define EDGE_SIZE2 (EDGE_SIZE/2)
71 :    
72 :    
73 :     int32_t
74 :     image_create(IMAGE * image,
75 :     uint32_t edged_width,
76 :     uint32_t edged_height)
77 :     {
78 :     const uint32_t edged_width2 = edged_width / 2;
79 :     const uint32_t edged_height2 = edged_height / 2;
80 :     uint32_t i;
81 :    
82 :     image->y =
83 :     xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE);
84 :     if (image->y == NULL) {
85 :     return -1;
86 :     }
87 :    
88 :     for (i = 0; i < edged_width * edged_height + SAFETY; i++) {
89 :     image->y[i] = 0;
90 :     }
91 :    
92 :     image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE);
93 :     if (image->u == NULL) {
94 :     xvid_free(image->y);
95 :     return -1;
96 :     }
97 :     image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE);
98 :     if (image->v == NULL) {
99 :     xvid_free(image->u);
100 :     xvid_free(image->y);
101 :     return -1;
102 :     }
103 :    
104 :     image->y += EDGE_SIZE * edged_width + EDGE_SIZE;
105 :     image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2;
106 :     image->v += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2;
107 :    
108 :     return 0;
109 :     }
110 :    
111 :    
112 :    
113 :     void
114 :     image_destroy(IMAGE * image,
115 :     uint32_t edged_width,
116 :     uint32_t edged_height)
117 :     {
118 :     const uint32_t edged_width2 = edged_width / 2;
119 :    
120 :     if (image->y) {
121 :     xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE));
122 :     }
123 :     if (image->u) {
124 :     xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2));
125 :     }
126 :     if (image->v) {
127 :     xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2));
128 :     }
129 :     }
130 :    
131 :    
132 :     void
133 :     image_swap(IMAGE * image1,
134 :     IMAGE * image2)
135 :     {
136 :     uint8_t *tmp;
137 :    
138 :     tmp = image1->y;
139 :     image1->y = image2->y;
140 :     image2->y = tmp;
141 :    
142 :     tmp = image1->u;
143 :     image1->u = image2->u;
144 :     image2->u = tmp;
145 :    
146 :     tmp = image1->v;
147 :     image1->v = image2->v;
148 :     image2->v = tmp;
149 :     }
150 :    
151 :    
152 :     void
153 :     image_copy(IMAGE * image1,
154 :     IMAGE * image2,
155 :     uint32_t edged_width,
156 :     uint32_t height)
157 :     {
158 :     memcpy(image1->y, image2->y, edged_width * height);
159 :     memcpy(image1->u, image2->u, edged_width * height / 4);
160 :     memcpy(image1->v, image2->v, edged_width * height / 4);
161 :     }
162 :    
163 :    
164 :     void
165 :     image_setedges(IMAGE * image,
166 :     uint32_t edged_width,
167 :     uint32_t edged_height,
168 :     uint32_t width,
169 : h 541 uint32_t height)
170 : albeu 315 {
171 :     const uint32_t edged_width2 = edged_width / 2;
172 :     const uint32_t width2 = width / 2;
173 :     uint32_t i;
174 :     uint8_t *dst;
175 :     uint8_t *src;
176 :    
177 :    
178 :     dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width);
179 :     src = image->y;
180 :    
181 :     for (i = 0; i < EDGE_SIZE; i++) {
182 :     memset(dst, *src, EDGE_SIZE);
183 :     memcpy(dst + EDGE_SIZE, src, width);
184 :     memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),
185 :     EDGE_SIZE);
186 :     dst += edged_width;
187 :     }
188 :    
189 :     for (i = 0; i < height; i++) {
190 :     memset(dst, *src, EDGE_SIZE);
191 :     memset(dst + edged_width - EDGE_SIZE, src[width - 1], EDGE_SIZE);
192 :     dst += edged_width;
193 :     src += edged_width;
194 :     }
195 :    
196 :     src -= edged_width;
197 :     for (i = 0; i < EDGE_SIZE; i++) {
198 :     memset(dst, *src, EDGE_SIZE);
199 :     memcpy(dst + EDGE_SIZE, src, width);
200 :     memset(dst + edged_width - EDGE_SIZE, *(src + width - 1),
201 :     EDGE_SIZE);
202 :     dst += edged_width;
203 :     }
204 :    
205 :    
206 : edgomez 677 /*U */
207 : albeu 315 dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);
208 :     src = image->u;
209 :    
210 :     for (i = 0; i < EDGE_SIZE2; i++) {
211 :     memset(dst, *src, EDGE_SIZE2);
212 :     memcpy(dst + EDGE_SIZE2, src, width2);
213 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
214 :     EDGE_SIZE2);
215 :     dst += edged_width2;
216 :     }
217 :    
218 :     for (i = 0; i < height / 2; i++) {
219 :     memset(dst, *src, EDGE_SIZE2);
220 :     memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2);
221 :     dst += edged_width2;
222 :     src += edged_width2;
223 :     }
224 :     src -= edged_width2;
225 :     for (i = 0; i < EDGE_SIZE2; i++) {
226 :     memset(dst, *src, EDGE_SIZE2);
227 :     memcpy(dst + EDGE_SIZE2, src, width2);
228 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
229 :     EDGE_SIZE2);
230 :     dst += edged_width2;
231 :     }
232 :    
233 :    
234 : edgomez 677 /* V */
235 : albeu 315 dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2);
236 :     src = image->v;
237 :    
238 :     for (i = 0; i < EDGE_SIZE2; i++) {
239 :     memset(dst, *src, EDGE_SIZE2);
240 :     memcpy(dst + EDGE_SIZE2, src, width2);
241 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
242 :     EDGE_SIZE2);
243 :     dst += edged_width2;
244 :     }
245 :    
246 :     for (i = 0; i < height / 2; i++) {
247 :     memset(dst, *src, EDGE_SIZE2);
248 :     memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2);
249 :     dst += edged_width2;
250 :     src += edged_width2;
251 :     }
252 :     src -= edged_width2;
253 :     for (i = 0; i < EDGE_SIZE2; i++) {
254 :     memset(dst, *src, EDGE_SIZE2);
255 :     memcpy(dst + EDGE_SIZE2, src, width2);
256 :     memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1),
257 :     EDGE_SIZE2);
258 :     dst += edged_width2;
259 :     }
260 :     }
261 :    
262 : edgomez 677 /* bframe encoding requires image-based u,v interpolation */
263 : albeu 315 void
264 :     image_interpolate(const IMAGE * refn,
265 :     IMAGE * refh,
266 :     IMAGE * refv,
267 :     IMAGE * refhv,
268 :     uint32_t edged_width,
269 :     uint32_t edged_height,
270 :     uint32_t rounding)
271 :     {
272 :     const uint32_t offset = EDGE_SIZE * (edged_width + 1);
273 :     const uint32_t stride_add = 7 * edged_width;
274 :    
275 :     uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr;
276 :     uint32_t x, y;
277 :    
278 :    
279 :     n_ptr = refn->y;
280 :     h_ptr = refh->y;
281 :     v_ptr = refv->y;
282 :     hv_ptr = refhv->y;
283 :    
284 :     n_ptr -= offset;
285 :     h_ptr -= offset;
286 :     v_ptr -= offset;
287 :     hv_ptr -= offset;
288 :    
289 :     for (y = 0; y < edged_height; y = y + 8) {
290 :     for (x = 0; x < edged_width; x = x + 8) {
291 :     interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding);
292 :     interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding);
293 :     interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding);
294 :    
295 :     n_ptr += 8;
296 :     h_ptr += 8;
297 :     v_ptr += 8;
298 :     hv_ptr += 8;
299 :     }
300 :     h_ptr += stride_add;
301 :     v_ptr += stride_add;
302 :     hv_ptr += stride_add;
303 :     n_ptr += stride_add;
304 :     }
305 :    
306 :     /*
307 :     interpolate_halfpel_h(
308 :     refh->y - offset,
309 :     refn->y - offset,
310 :     edged_width, edged_height,
311 :     rounding);
312 :    
313 :     interpolate_halfpel_v(
314 :     refv->y - offset,
315 :     refn->y - offset,
316 :     edged_width, edged_height,
317 :     rounding);
318 :    
319 :     interpolate_halfpel_hv(
320 :     refhv->y - offset,
321 :     refn->y - offset,
322 :     edged_width, edged_height,
323 :     rounding);
324 :     */
325 :    
326 :     /* uv-image-based compensation
327 :     offset = EDGE_SIZE2 * (edged_width / 2 + 1);
328 :    
329 :     interpolate_halfpel_h(
330 :     refh->u - offset,
331 :     refn->u - offset,
332 :     edged_width / 2, edged_height / 2,
333 :     rounding);
334 :    
335 :     interpolate_halfpel_v(
336 :     refv->u - offset,
337 :     refn->u - offset,
338 :     edged_width / 2, edged_height / 2,
339 :     rounding);
340 :    
341 :     interpolate_halfpel_hv(
342 :     refhv->u - offset,
343 :     refn->u - offset,
344 :     edged_width / 2, edged_height / 2,
345 :     rounding);
346 :    
347 :    
348 :     interpolate_halfpel_h(
349 :     refh->v - offset,
350 :     refn->v - offset,
351 :     edged_width / 2, edged_height / 2,
352 :     rounding);
353 :    
354 :     interpolate_halfpel_v(
355 :     refv->v - offset,
356 :     refn->v - offset,
357 :     edged_width / 2, edged_height / 2,
358 :     rounding);
359 :    
360 :     interpolate_halfpel_hv(
361 :     refhv->v - offset,
362 :     refn->v - offset,
363 :     edged_width / 2, edged_height / 2,
364 :     rounding);
365 :     */
366 :     }
367 :    
368 :    
369 :     int
370 :     image_input(IMAGE * image,
371 :     uint32_t width,
372 :     int height,
373 :     uint32_t edged_width,
374 :     uint8_t * src,
375 :     int csp)
376 :     {
377 :    
378 :     /* if (csp & XVID_CSP_VFLIP)
379 :     {
380 :     height = -height;
381 :     }
382 :     */
383 :    
384 :     switch (csp & ~XVID_CSP_VFLIP) {
385 :     case XVID_CSP_RGB555:
386 :     rgb555_to_yv12(image->y, image->u, image->v, src, width, height,
387 :     edged_width);
388 :     return 0;
389 :    
390 :     case XVID_CSP_RGB565:
391 :     rgb565_to_yv12(image->y, image->u, image->v, src, width, height,
392 :     edged_width);
393 :     return 0;
394 :    
395 :    
396 :     case XVID_CSP_RGB24:
397 :     rgb24_to_yv12(image->y, image->u, image->v, src, width, height,
398 :     edged_width);
399 :     return 0;
400 :    
401 :     case XVID_CSP_RGB32:
402 :     rgb32_to_yv12(image->y, image->u, image->v, src, width, height,
403 :     edged_width);
404 :     return 0;
405 :    
406 :     case XVID_CSP_I420:
407 :     yuv_to_yv12(image->y, image->u, image->v, src, width, height,
408 :     edged_width);
409 :     return 0;
410 :    
411 :     case XVID_CSP_YV12: /* u/v swapped */
412 :     yuv_to_yv12(image->y, image->v, image->u, src, width, height,
413 :     edged_width);
414 :     return 0;
415 :    
416 :     case XVID_CSP_YUY2:
417 :     yuyv_to_yv12(image->y, image->u, image->v, src, width, height,
418 :     edged_width);
419 :     return 0;
420 :    
421 :     case XVID_CSP_YVYU: /* u/v swapped */
422 :     yuyv_to_yv12(image->y, image->v, image->u, src, width, height,
423 :     edged_width);
424 :     return 0;
425 :    
426 :     case XVID_CSP_UYVY:
427 :     uyvy_to_yv12(image->y, image->u, image->v, src, width, height,
428 :     edged_width);
429 :     return 0;
430 :    
431 :     case XVID_CSP_USER:
432 :     user_to_yuv_c(image->y, image->u, image->v, edged_width,
433 :     (DEC_PICTURE *) src, width, height);
434 :     return 0;
435 :    
436 :     case XVID_CSP_NULL:
437 :     break;
438 :    
439 :     }
440 :    
441 :     return -1;
442 :     }
443 :    
444 :    
445 :    
446 :     int
447 :     image_output(IMAGE * image,
448 :     uint32_t width,
449 :     int height,
450 :     uint32_t edged_width,
451 :     uint8_t * dst,
452 :     uint32_t dst_stride,
453 :     int csp)
454 :     {
455 :     if (csp & XVID_CSP_VFLIP) {
456 :     height = -height;
457 :     }
458 :    
459 :     switch (csp & ~XVID_CSP_VFLIP) {
460 :     case XVID_CSP_RGB555:
461 :     yv12_to_rgb555(dst, dst_stride, image->y, image->u, image->v,
462 :     edged_width, edged_width / 2, width, height);
463 :     return 0;
464 :    
465 :     case XVID_CSP_RGB565:
466 :     yv12_to_rgb565(dst, dst_stride, image->y, image->u, image->v,
467 :     edged_width, edged_width / 2, width, height);
468 :     return 0;
469 :    
470 :     case XVID_CSP_RGB24:
471 :     yv12_to_rgb24(dst, dst_stride, image->y, image->u, image->v,
472 :     edged_width, edged_width / 2, width, height);
473 :     return 0;
474 :    
475 :     case XVID_CSP_RGB32:
476 :     yv12_to_rgb32(dst, dst_stride, image->y, image->u, image->v,
477 :     edged_width, edged_width / 2, width, height);
478 :     return 0;
479 :    
480 :     case XVID_CSP_I420:
481 :     yv12_to_yuv(dst, dst_stride, image->y, image->u, image->v, edged_width,
482 :     edged_width / 2, width, height);
483 :     return 0;
484 :    
485 : edgomez 677 case XVID_CSP_YV12: /* u,v swapped */
486 : albeu 315 yv12_to_yuv(dst, dst_stride, image->y, image->v, image->u, edged_width,
487 :     edged_width / 2, width, height);
488 :     return 0;
489 :    
490 :     case XVID_CSP_YUY2:
491 :     yv12_to_yuyv(dst, dst_stride, image->y, image->u, image->v,
492 :     edged_width, edged_width / 2, width, height);
493 :     return 0;
494 :    
495 : edgomez 677 case XVID_CSP_YVYU: /* u,v swapped */
496 : albeu 315 yv12_to_yuyv(dst, dst_stride, image->y, image->v, image->u,
497 :     edged_width, edged_width / 2, width, height);
498 :     return 0;
499 :    
500 :     case XVID_CSP_UYVY:
501 :     yv12_to_uyvy(dst, dst_stride, image->y, image->u, image->v,
502 :     edged_width, edged_width / 2, width, height);
503 :     return 0;
504 :    
505 :     case XVID_CSP_USER:
506 :     ((DEC_PICTURE *) dst)->y = image->y;
507 :     ((DEC_PICTURE *) dst)->u = image->u;
508 :     ((DEC_PICTURE *) dst)->v = image->v;
509 :     ((DEC_PICTURE *) dst)->stride_y = edged_width;
510 :     ((DEC_PICTURE *) dst)->stride_uv = edged_width / 2;
511 :     return 0;
512 :    
513 :     case XVID_CSP_NULL:
514 :     case XVID_CSP_EXTERN:
515 :     return 0;
516 :    
517 :     }
518 :    
519 :     return -1;
520 :     }
521 :    
522 :     float
523 :     image_psnr(IMAGE * orig_image,
524 :     IMAGE * recon_image,
525 :     uint16_t stride,
526 :     uint16_t width,
527 :     uint16_t height)
528 :     {
529 :     int32_t diff, x, y, quad = 0;
530 :     uint8_t *orig = orig_image->y;
531 :     uint8_t *recon = recon_image->y;
532 :     float psnr_y;
533 :    
534 :     for (y = 0; y < height; y++) {
535 :     for (x = 0; x < width; x++) {
536 :     diff = *(orig + x) - *(recon + x);
537 :     quad += diff * diff;
538 :     }
539 :     orig += stride;
540 :     recon += stride;
541 :     }
542 :    
543 :     psnr_y = (float) quad / (float) (width * height);
544 :    
545 :     if (psnr_y) {
546 :     psnr_y = (float) (255 * 255) / psnr_y;
547 :     psnr_y = 10 * (float) log10(psnr_y);
548 :     } else
549 :     psnr_y = (float) 99.99;
550 :    
551 :     return psnr_y;
552 :     }
553 :    
554 : edgomez 677 #if 0
555 : albeu 315
556 :     #include <stdio.h>
557 :     #include <string.h>
558 :    
559 :     int image_dump_pgm(uint8_t * bmp, uint32_t width, uint32_t height, char * filename)
560 :     {
561 :     FILE * f;
562 :     char hdr[1024];
563 :    
564 :     f = fopen(filename, "wb");
565 :     if ( f == NULL)
566 :     {
567 :     return -1;
568 :     }
569 :     sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, height);
570 :     fwrite(hdr, strlen(hdr), 1, f);
571 :     fwrite(bmp, width, height, f);
572 :     fclose(f);
573 :    
574 :     return 0;
575 :     }
576 :    
577 :    
578 : edgomez 677 /* dump image+edges to yuv pgm files */
579 : albeu 315
580 :     int image_dump(IMAGE * image, uint32_t edged_width, uint32_t edged_height, char * path, int number)
581 :     {
582 :     char filename[1024];
583 :    
584 :     sprintf(filename, "%s_%i_%c.pgm", path, number, 'y');
585 :     image_dump_pgm(
586 :     image->y - (EDGE_SIZE * edged_width + EDGE_SIZE),
587 :     edged_width, edged_height, filename);
588 :    
589 :     sprintf(filename, "%s_%i_%c.pgm", path, number, 'u');
590 :     image_dump_pgm(
591 :     image->u - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2),
592 :     edged_width / 2, edged_height / 2, filename);
593 :    
594 :     sprintf(filename, "%s_%i_%c.pgm", path, number, 'v');
595 :     image_dump_pgm(
596 :     image->v - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2),
597 :     edged_width / 2, edged_height / 2, filename);
598 :    
599 :     return 0;
600 :     }
601 : edgomez 677 #endif
602 : albeu 315
603 :    
604 :    
605 :     /* dump image to yuvpgm file */
606 :    
607 :     #include <stdio.h>
608 :    
609 :     int
610 :     image_dump_yuvpgm(const IMAGE * image,
611 :     const uint32_t edged_width,
612 :     const uint32_t width,
613 :     const uint32_t height,
614 :     char *filename)
615 :     {
616 :     FILE *f;
617 :     char hdr[1024];
618 :     uint32_t i;
619 :     uint8_t *bmp1;
620 :     uint8_t *bmp2;
621 :    
622 :    
623 :     f = fopen(filename, "wb");
624 :     if (f == NULL) {
625 :     return -1;
626 :     }
627 :     sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, (3 * height) / 2);
628 :     fwrite(hdr, strlen(hdr), 1, f);
629 :    
630 :     bmp1 = image->y;
631 :     for (i = 0; i < height; i++) {
632 :     fwrite(bmp1, width, 1, f);
633 :     bmp1 += edged_width;
634 :     }
635 :    
636 :     bmp1 = image->u;
637 :     bmp2 = image->v;
638 :     for (i = 0; i < height / 2; i++) {
639 :     fwrite(bmp1, width / 2, 1, f);
640 :     fwrite(bmp2, width / 2, 1, f);
641 :     bmp1 += edged_width / 2;
642 :     bmp2 += edged_width / 2;
643 :     }
644 :    
645 :     fclose(f);
646 :     return 0;
647 :     }
648 :    
649 :    
650 :     #define ABS(X) (((X)>0)?(X):-(X))
651 :     float
652 :     image_mad(const IMAGE * img1,
653 :     const IMAGE * img2,
654 :     uint32_t stride,
655 :     uint32_t width,
656 :     uint32_t height)
657 :     {
658 :     const uint32_t stride2 = stride / 2;
659 :     const uint32_t width2 = width / 2;
660 :     const uint32_t height2 = height / 2;
661 :    
662 :     uint32_t x, y;
663 :     uint32_t sum = 0;
664 :    
665 :     for (y = 0; y < height; y++)
666 :     for (x = 0; x < width; x++)
667 :     sum += ABS(img1->y[x + y * stride] - img2->y[x + y * stride]);
668 :    
669 :     for (y = 0; y < height2; y++)
670 :     for (x = 0; x < width2; x++)
671 :     sum += ABS(img1->u[x + y * stride2] - img2->u[x + y * stride2]);
672 :    
673 :     for (y = 0; y < height2; y++)
674 :     for (x = 0; x < width2; x++)
675 :     sum += ABS(img1->v[x + y * stride2] - img2->v[x + y * stride2]);
676 :    
677 :     return (float) sum / (width * height * 3 / 2);
678 :     }
679 :    
680 :     void
681 :     output_slice(IMAGE * cur, int std, int width, XVID_DEC_PICTURE* out_frm, int mbx, int mby,int mbl) {
682 :     uint8_t *dY,*dU,*dV,*sY,*sU,*sV;
683 :     int std2 = std >> 1;
684 :     int w = mbl << 4, w2,i;
685 :    
686 :     if(w > width)
687 :     w = width;
688 :     w2 = w >> 1;
689 : suxen_drol 323
690 : albeu 315 dY = (uint8_t*)out_frm->y + (mby << 4) * out_frm->stride_y + (mbx << 4);
691 :     dU = (uint8_t*)out_frm->u + (mby << 3) * out_frm->stride_u + (mbx << 3);
692 :     dV = (uint8_t*)out_frm->v + (mby << 3) * out_frm->stride_v + (mbx << 3);
693 :     sY = cur->y + (mby << 4) * std + (mbx << 4);
694 :     sU = cur->u + (mby << 3) * std2 + (mbx << 3);
695 :     sV = cur->v + (mby << 3) * std2 + (mbx << 3);
696 :    
697 :     for(i = 0 ; i < 16 ; i++) {
698 :     memcpy(dY,sY,w);
699 : suxen_drol 323 dY += out_frm->stride_y;
700 :     sY += std;
701 :     }
702 : albeu 315 for(i = 0 ; i < 8 ; i++) {
703 :     memcpy(dU,sU,w2);
704 :     dU += out_frm->stride_u;
705 :     sU += std2;
706 :     }
707 :     for(i = 0 ; i < 8 ; i++) {
708 :     memcpy(dV,sV,w2);
709 :     dV += out_frm->stride_v;
710 :     sV += std2;
711 :     }
712 :     }

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