[svn] / trunk / xvidcore / src / image / image.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/image/image.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 433 - (view) (download)

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

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