1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "filters.h"
18 #include <stdio.h>
19
flipVertical(char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)20 static __inline__ void flipVertical(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
21 //Vertical
22 size_t cpy_bytes = sizeof(char) * 4;
23 int width = cpy_bytes * srcWidth;
24 int length = srcHeight;
25 int total = length * width;
26 size_t bytes_to_copy = sizeof(char) * width;
27 int i = 0;
28 int temp = total - width;
29 for (i = 0; i < total; i += width) {
30 memcpy(destination + temp - i, source + i, bytes_to_copy);
31 }
32 }
33
flipHorizontal(char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)34 static __inline__ void flipHorizontal(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
35 //Horizontal
36 size_t cpy_bytes = sizeof(char) * 4;
37 int width = cpy_bytes * srcWidth;
38 int length = srcHeight;
39 int total = length * width;
40 int i = 0;
41 int j = 0;
42 int temp = 0;
43 for (i = 0; i < total; i+= width) {
44 temp = width + i - cpy_bytes;
45 for (j = 0; j < width; j+=cpy_bytes) {
46 memcpy(destination + temp - j, source + i + j, cpy_bytes);
47 }
48 }
49 }
50
flip_fun(int flip,char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)51 static __inline__ void flip_fun(int flip, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
52 int horiz = (flip & 1) != 0;
53 int vert = (flip & 2) != 0;
54 if (horiz && vert){
55 int arr_len = dstWidth * dstHeight * sizeof(char) * 4;
56 char* temp = (char *) malloc(arr_len);
57 flipHorizontal(source, srcWidth, srcHeight, temp, dstWidth, dstHeight);
58 flipVertical(temp, dstWidth, dstHeight, destination, dstWidth, dstHeight);
59 free(temp);
60 return;
61 }
62 if (horiz){
63 flipHorizontal(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
64 return;
65 }
66 if (vert){
67 flipVertical(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
68 return;
69 }
70 }
71
72 //90 CCW (opposite of what's used in UI?)
rotate90(char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)73 static __inline__ void rotate90(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
74 size_t cpy_bytes = sizeof(char) * 4;
75 int width = cpy_bytes * srcWidth;
76 int length = srcHeight;
77 int total = length * width;
78 int i = 0;
79 int j = 0;
80 for (j = 0; j < length * cpy_bytes; j+= cpy_bytes){
81 for (i = 0; i < width; i+=cpy_bytes){
82 int column_disp = (width - cpy_bytes - i) * length;
83 int row_disp = j;
84 memcpy(destination + column_disp + row_disp , source + j * srcWidth + i, cpy_bytes);
85 }
86 }
87 }
88
rotate180(char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)89 static __inline__ void rotate180(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
90 flip_fun(3, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
91 }
92
rotate270(char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)93 static __inline__ void rotate270(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
94 rotate90(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
95 flip_fun(3, destination, dstWidth, dstHeight, destination, dstWidth, dstHeight);
96 }
97
98 // rotate == 1 is 90 degrees, 2 is 180, 3 is 270 (positive is CCW).
rotate_fun(int rotate,char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight)99 static __inline__ void rotate_fun(int rotate, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
100 switch( rotate )
101 {
102 case 1:
103 rotate90(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
104 break;
105 case 2:
106 rotate180(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
107 break;
108 case 3:
109 rotate270(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
110 break;
111 default:
112 break;
113 }
114 }
115
crop(char * source,int srcWidth,int srcHeight,char * destination,int dstWidth,int dstHeight,int offsetWidth,int offsetHeight)116 static __inline__ void crop(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight, int offsetWidth, int offsetHeight){
117 size_t cpy_bytes = sizeof(char) * 4;
118 int row_width = cpy_bytes * srcWidth;
119 int new_row_width = cpy_bytes * dstWidth;
120 if ((srcWidth > dstWidth + offsetWidth) || (srcHeight > dstHeight + offsetHeight)){
121 return;
122 }
123 int i = 0;
124 int j = 0;
125 for (j = offsetHeight; j < offsetHeight + dstHeight; j++){
126 memcpy(destination + (j - offsetHeight) * new_row_width, source + j * row_width + offsetWidth * cpy_bytes, cpy_bytes * dstWidth );
127 }
128 }
129
JNIFUNCF(ImageFilterGeometry,nativeApplyFilterFlip,jobject src,jint srcWidth,jint srcHeight,jobject dst,jint dstWidth,jint dstHeight,jint flip)130 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterFlip, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint flip) {
131 char* destination = 0;
132 char* source = 0;
133 if (srcWidth != dstWidth || srcHeight != dstHeight) {
134 return;
135 }
136 AndroidBitmap_lockPixels(env, src, (void**) &source);
137 AndroidBitmap_lockPixels(env, dst, (void**) &destination);
138 flip_fun(flip, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
139 AndroidBitmap_unlockPixels(env, dst);
140 AndroidBitmap_unlockPixels(env, src);
141 }
142
JNIFUNCF(ImageFilterGeometry,nativeApplyFilterRotate,jobject src,jint srcWidth,jint srcHeight,jobject dst,jint dstWidth,jint dstHeight,jint rotate)143 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterRotate, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint rotate) {
144 char* destination = 0;
145 char* source = 0;
146 int len = dstWidth * dstHeight * 4;
147 AndroidBitmap_lockPixels(env, src, (void**) &source);
148 AndroidBitmap_lockPixels(env, dst, (void**) &destination);
149 rotate_fun(rotate, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
150 AndroidBitmap_unlockPixels(env, dst);
151 AndroidBitmap_unlockPixels(env, src);
152 }
153
JNIFUNCF(ImageFilterGeometry,nativeApplyFilterCrop,jobject src,jint srcWidth,jint srcHeight,jobject dst,jint dstWidth,jint dstHeight,jint offsetWidth,jint offsetHeight)154 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterCrop, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint offsetWidth, jint offsetHeight) {
155 char* destination = 0;
156 char* source = 0;
157 int len = dstWidth * dstHeight * 4;
158 AndroidBitmap_lockPixels(env, src, (void**) &source);
159 AndroidBitmap_lockPixels(env, dst, (void**) &destination);
160 crop(source, srcWidth, srcHeight, destination, dstWidth, dstHeight, offsetWidth, offsetHeight);
161 AndroidBitmap_unlockPixels(env, dst);
162 AndroidBitmap_unlockPixels(env, src);
163 }
164
JNIFUNCF(ImageFilterGeometry,nativeApplyFilterStraighten,jobject src,jint srcWidth,jint srcHeight,jobject dst,jint dstWidth,jint dstHeight,jfloat straightenAngle)165 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jfloat straightenAngle) {
166 char* destination = 0;
167 char* source = 0;
168 int len = dstWidth * dstHeight * 4;
169 AndroidBitmap_lockPixels(env, src, (void**) &source);
170 AndroidBitmap_lockPixels(env, dst, (void**) &destination);
171 // TODO: implement straighten
172 int i = 0;
173 for (; i < len; i += 4) {
174 int r = source[RED];
175 int g = source[GREEN];
176 int b = source[BLUE];
177 destination[RED] = 128;
178 destination[GREEN] = g;
179 destination[BLUE] = 128;
180 }
181 AndroidBitmap_unlockPixels(env, dst);
182 AndroidBitmap_unlockPixels(env, src);
183 }
184
185