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

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