📄 image.c
字号:
/***************************************************************************** * * XVID MPEG-4 VIDEO CODEC * - image module - * * Copyright(C) 2002 Peter Ross <pross@xvid.org> * * This file is part of XviD, a free MPEG-4 video encoder/decoder * * XviD is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Under section 8 of the GNU General Public License, the copyright * holders of XVID explicitly forbid distribution in the following * countries: * * - Japan * - United States of America * * Linking XviD statically or dynamically with other modules is making a * combined work based on XviD. Thus, the terms and conditions of the * GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of XviD give you * permission to link XviD with independent modules that communicate with * XviD solely through the VFW1.1 and DShow interfaces, regardless of the * license terms of these independent modules, and to copy and distribute * the resulting combined work under terms of your choice, provided that * every copy of the combined work is accompanied by a complete copy of * the source code of XviD (the version of XviD used to produce the * combined work), being distributed under the terms of the GNU General * Public License plus this exception. An independent module is a module * which is not derived from or based on XviD. * * Note that people who make modified versions of XviD are not obligated * to grant this special exception for their modified versions; it is * their choice whether to do so. The GNU General Public License gives * permission to release a modified version without this exception; this * exception also makes it possible to release a modified version which * carries forward this exception. * * $Id: image.c,v 1.25 2002/11/26 23:44:10 edgomez Exp $ * ****************************************************************************/#include <stdlib.h>#include <string.h> /* memcpy, memset */#include <math.h>#include "../portab.h"#include "../xvid.h" /* XVID_CSP_XXX's */#include "image.h"#include "colorspace.h"#include "interpolate8x8.h"#include "../divx4.h"#include "../utils/mem_align.h"#define SAFETY 64#define EDGE_SIZE2 (EDGE_SIZE/2)int32_timage_create(IMAGE * image, uint32_t edged_width, uint32_t edged_height){ const uint32_t edged_width2 = edged_width / 2; const uint32_t edged_height2 = edged_height / 2; uint32_t i; image->y = xvid_malloc(edged_width * (edged_height + 1) + SAFETY, CACHE_LINE); if (image->y == NULL) { return -1; } for (i = 0; i < edged_width * edged_height + SAFETY; i++) { image->y[i] = 0; } image->u = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); if (image->u == NULL) { xvid_free(image->y); return -1; } image->v = xvid_malloc(edged_width2 * edged_height2 + SAFETY, CACHE_LINE); if (image->v == NULL) { xvid_free(image->u); xvid_free(image->y); return -1; } image->y += EDGE_SIZE * edged_width + EDGE_SIZE; image->u += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2; image->v += EDGE_SIZE2 * edged_width2 + EDGE_SIZE2; return 0;}voidimage_destroy(IMAGE * image, uint32_t edged_width, uint32_t edged_height){ const uint32_t edged_width2 = edged_width / 2; if (image->y) { xvid_free(image->y - (EDGE_SIZE * edged_width + EDGE_SIZE)); } if (image->u) { xvid_free(image->u - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); } if (image->v) { xvid_free(image->v - (EDGE_SIZE2 * edged_width2 + EDGE_SIZE2)); }}voidimage_swap(IMAGE * image1, IMAGE * image2){ uint8_t *tmp; tmp = image1->y; image1->y = image2->y; image2->y = tmp; tmp = image1->u; image1->u = image2->u; image2->u = tmp; tmp = image1->v; image1->v = image2->v; image2->v = tmp;}voidimage_copy(IMAGE * image1, IMAGE * image2, uint32_t edged_width, uint32_t height){ memcpy(image1->y, image2->y, edged_width * height); memcpy(image1->u, image2->u, edged_width * height / 4); memcpy(image1->v, image2->v, edged_width * height / 4);}voidimage_setedges(IMAGE * image, uint32_t edged_width, uint32_t edged_height, uint32_t width, uint32_t height){ const uint32_t edged_width2 = edged_width / 2; const uint32_t width2 = width / 2; uint32_t i; uint8_t *dst; uint8_t *src; dst = image->y - (EDGE_SIZE + EDGE_SIZE * edged_width); src = image->y; for (i = 0; i < EDGE_SIZE; i++) { memset(dst, *src, EDGE_SIZE); memcpy(dst + EDGE_SIZE, src, width); memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), EDGE_SIZE); dst += edged_width; } for (i = 0; i < height; i++) { memset(dst, *src, EDGE_SIZE); memset(dst + edged_width - EDGE_SIZE, src[width - 1], EDGE_SIZE); dst += edged_width; src += edged_width; } src -= edged_width; for (i = 0; i < EDGE_SIZE; i++) { memset(dst, *src, EDGE_SIZE); memcpy(dst + EDGE_SIZE, src, width); memset(dst + edged_width - EDGE_SIZE, *(src + width - 1), EDGE_SIZE); dst += edged_width; }/*U */ dst = image->u - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2); src = image->u; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; } for (i = 0; i < height / 2; i++) { memset(dst, *src, EDGE_SIZE2); memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2); dst += edged_width2; src += edged_width2; } src -= edged_width2; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; }/* V */ dst = image->v - (EDGE_SIZE2 + EDGE_SIZE2 * edged_width2); src = image->v; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; } for (i = 0; i < height / 2; i++) { memset(dst, *src, EDGE_SIZE2); memset(dst + edged_width2 - EDGE_SIZE2, src[width2 - 1], EDGE_SIZE2); dst += edged_width2; src += edged_width2; } src -= edged_width2; for (i = 0; i < EDGE_SIZE2; i++) { memset(dst, *src, EDGE_SIZE2); memcpy(dst + EDGE_SIZE2, src, width2); memset(dst + edged_width2 - EDGE_SIZE2, *(src + width2 - 1), EDGE_SIZE2); dst += edged_width2; }}/* bframe encoding requires image-based u,v interpolation */voidimage_interpolate(const IMAGE * refn, IMAGE * refh, IMAGE * refv, IMAGE * refhv, uint32_t edged_width, uint32_t edged_height, uint32_t rounding){ const uint32_t offset = EDGE_SIZE * (edged_width + 1); const uint32_t stride_add = 7 * edged_width; uint8_t *n_ptr, *h_ptr, *v_ptr, *hv_ptr; uint32_t x, y; n_ptr = refn->y; h_ptr = refh->y; v_ptr = refv->y; hv_ptr = refhv->y; n_ptr -= offset; h_ptr -= offset; v_ptr -= offset; hv_ptr -= offset; for (y = 0; y < edged_height; y = y + 8) { for (x = 0; x < edged_width; x = x + 8) { interpolate8x8_halfpel_h(h_ptr, n_ptr, edged_width, rounding); interpolate8x8_halfpel_v(v_ptr, n_ptr, edged_width, rounding); interpolate8x8_halfpel_hv(hv_ptr, n_ptr, edged_width, rounding); n_ptr += 8; h_ptr += 8; v_ptr += 8; hv_ptr += 8; } h_ptr += stride_add; v_ptr += stride_add; hv_ptr += stride_add; n_ptr += stride_add; } /* interpolate_halfpel_h( refh->y - offset, refn->y - offset, edged_width, edged_height, rounding); interpolate_halfpel_v( refv->y - offset, refn->y - offset, edged_width, edged_height, rounding); interpolate_halfpel_hv( refhv->y - offset, refn->y - offset, edged_width, edged_height, rounding); */ /* uv-image-based compensation offset = EDGE_SIZE2 * (edged_width / 2 + 1); interpolate_halfpel_h( refh->u - offset, refn->u - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_v( refv->u - offset, refn->u - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_hv( refhv->u - offset, refn->u - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_h( refh->v - offset, refn->v - offset, edged_width / 2, edged_height / 2, rounding); interpolate_halfpel_v( refv->v - offset, refn->v - offset, edged_width / 2, edged_height / 2,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -