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

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