OSDN Git Service

am 7537e615: (-s ours) am 53851696: (-s ours) Import translations. DO NOT MERGE
[android-x86/packages-apps-Gallery2.git] / jni / filters / geometry.c
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
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
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
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?)
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
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
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).
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
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
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
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
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
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