📄 rotate90_u16.c
字号:
/* * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. *//* * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License * Version 2 or later at the following locations: * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */#include <linux/module.h>#include "opl.h"static int opl_rotate90_u16_by16(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride, int vmirror);static int opl_rotate90_u16_by4(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride, int vmirror);static int opl_rotate90_vmirror_u16_both(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride, int vmirror);int opl_rotate90_u16_qcif(const u8 * src, u8 * dst);int opl_rotate90_u16(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride){ return opl_rotate90_vmirror_u16_both(src, src_line_stride, width, height, dst, dst_line_stride, 0);}int opl_rotate90_vmirror_u16(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride){ return opl_rotate90_vmirror_u16_both(src, src_line_stride, width, height, dst, dst_line_stride, 1);}static int opl_rotate90_vmirror_u16_both(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride, int vmirror){ const int BLOCK_SIZE_PIXELS = CACHE_LINE_WORDS * BYTES_PER_WORD / BYTES_PER_PIXEL; const int BLOCK_SIZE_PIXELS_BY4 = CACHE_LINE_WORDS * BYTES_PER_WORD / BYTES_PER_PIXEL / 4; if (!src || !dst) return OPLERR_NULL_PTR; if (width == 0 || height == 0 || src_line_stride == 0 || dst_line_stride == 0) return OPLERR_BAD_ARG; /* The QCIF algorithm doesn't support vertical mirroring */ if (vmirror == 0 && width == QCIF_Y_WIDTH && height == QCIF_Y_HEIGHT && src_line_stride == QCIF_Y_WIDTH * 2 && src_line_stride == QCIF_Y_HEIGHT * 2) return opl_rotate90_u16_qcif(src, dst); else if (width % BLOCK_SIZE_PIXELS == 0 && height % BLOCK_SIZE_PIXELS == 0) return opl_rotate90_u16_by16(src, src_line_stride, width, height, dst, dst_line_stride, vmirror); else if (width % BLOCK_SIZE_PIXELS_BY4 == 0 && height % BLOCK_SIZE_PIXELS_BY4 == 0) return opl_rotate90_u16_by4(src, src_line_stride, width, height, dst, dst_line_stride, vmirror); else return OPLERR_BAD_ARG;}/* * Performs clockwise rotation (and possibly vertical mirroring depending * on the vmirror flag) using block sizes of 16x16 * The algorithm is similar to 270 degree clockwise rotation algorithm */static int opl_rotate90_u16_by16(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride, int vmirror){ const int BLOCK_SIZE_PIXELS = CACHE_LINE_WORDS * BYTES_PER_WORD / BYTES_PER_PIXEL; const int BLOCK_SIZE_BYTES = BYTES_PER_PIXEL * BLOCK_SIZE_PIXELS; const int IN_INDEX = src_line_stride * BLOCK_SIZE_PIXELS + BYTES_PER_PIXEL; const int OUT_INDEX = vmirror ? -dst_line_stride - BLOCK_SIZE_BYTES : dst_line_stride - BLOCK_SIZE_BYTES; const u8 *in_block_ptr; u8 *out_block_ptr; int i, k; for (k = height / BLOCK_SIZE_PIXELS; k > 0; k--) { in_block_ptr = src + src_line_stride * (height - 1) - (src_line_stride * BLOCK_SIZE_PIXELS * (height / BLOCK_SIZE_PIXELS - k)); out_block_ptr = dst + BYTES_PER_PIXEL * BLOCK_SIZE_PIXELS * ((height / BLOCK_SIZE_PIXELS) - k); /* * For vertical mirroring the writing starts from the * bottom line */ if (vmirror) out_block_ptr += dst_line_stride * (width - 1); for (i = width; i > 0; i--) { __asm__ volatile ( "ldrh r2, [%0], -%4\n\t" "ldrh r3, [%0], -%4\n\t" "ldrh r4, [%0], -%4\n\t" "ldrh r5, [%0], -%4\n\t" "orr r2, r2, r3, lsl #16\n\t" "orr r4, r4, r5, lsl #16\n\t" "str r2, [%1], #4\n\t" "str r4, [%1], #4\n\t" "ldrh r2, [%0], -%4\n\t" "ldrh r3, [%0], -%4\n\t" "ldrh r4, [%0], -%4\n\t" "ldrh r5, [%0], -%4\n\t" "orr r2, r2, r3, lsl #16\n\t" "orr r4, r4, r5, lsl #16\n\t" "str r2, [%1], #4\n\t" "str r4, [%1], #4\n\t" "ldrh r2, [%0], -%4\n\t" "ldrh r3, [%0], -%4\n\t" "ldrh r4, [%0], -%4\n\t" "ldrh r5, [%0], -%4\n\t" "orr r2, r2, r3, lsl #16\n\t" "orr r4, r4, r5, lsl #16\n\t" "str r2, [%1], #4\n\t" "str r4, [%1], #4\n\t" "ldrh r2, [%0], -%4\n\t" "ldrh r3, [%0], -%4\n\t" "ldrh r4, [%0], -%4\n\t" "ldrh r5, [%0], -%4\n\t" "orr r2, r2, r3, lsl #16\n\t" "orr r4, r4, r5, lsl #16\n\t" "str r2, [%1], #4\n\t" "str r4, [%1], #4\n\t" :"+r" (in_block_ptr), "+r"(out_block_ptr) /* output */ :"0"(in_block_ptr), "1"(out_block_ptr), "r"(src_line_stride) /* input */ :"r2", "r3", "r4", "r5", "memory" /* modify */ ); in_block_ptr += IN_INDEX; out_block_ptr += OUT_INDEX; } } return OPLERR_SUCCESS;}/* * Performs clockwise rotation (and possibly vertical mirroring depending * on the vmirror flag) using block sizes of 4x4 * The algorithm is similar to 270 degree clockwise rotation algorithm */static int opl_rotate90_u16_by4(const u8 * src, int src_line_stride, int width, int height, u8 * dst, int dst_line_stride, int vmirror){ const int BLOCK_SIZE_PIXELS = CACHE_LINE_WORDS * BYTES_PER_WORD / BYTES_PER_PIXEL / 4; const int BLOCK_SIZE_BYTES = BYTES_PER_PIXEL * BLOCK_SIZE_PIXELS; const int IN_INDEX = src_line_stride * BLOCK_SIZE_PIXELS + BYTES_PER_PIXEL; const int OUT_INDEX = vmirror ? -dst_line_stride - BLOCK_SIZE_BYTES : dst_line_stride - BLOCK_SIZE_BYTES; const u8 *in_block_ptr; u8 *out_block_ptr; int i, k; for (k = height / BLOCK_SIZE_PIXELS; k > 0; k--) { in_block_ptr = src + src_line_stride * (height - 1) - (src_line_stride * BLOCK_SIZE_PIXELS * (height / BLOCK_SIZE_PIXELS - k)); out_block_ptr = dst + BYTES_PER_PIXEL * BLOCK_SIZE_PIXELS * ((height / BLOCK_SIZE_PIXELS) - k); /* * For horizontal mirroring the writing starts from the * bottom line */ if (vmirror) out_block_ptr += dst_line_stride * (width - 1); for (i = width; i > 0; i--) { __asm__ volatile ( "ldrh r2, [%0], -%4\n\t" "ldrh r3, [%0], -%4\n\t" "ldrh r4, [%0], -%4\n\t" "ldrh r5, [%0], -%4\n\t" "orr r2, r2, r3, lsl #16\n\t" "orr r4, r4, r5, lsl #16\n\t" "str r2, [%1], #4\n\t" "str r4, [%1], #4\n\t" :"+r" (in_block_ptr), "+r"(out_block_ptr) /* output */ :"0"(in_block_ptr), "1"(out_block_ptr), "r"(src_line_stride) /* input */ :"r2", "r3", "r4", "r5", "memory" /* modify */ ); in_block_ptr += IN_INDEX; out_block_ptr += OUT_INDEX; } } return OPLERR_SUCCESS;}EXPORT_SYMBOL(opl_rotate90_u16);EXPORT_SYMBOL(opl_rotate90_vmirror_u16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -