[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 315 - (view) (download)
Original Path: trunk/xvidcore/src/image/image.c

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

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