OSDN Git Service

8537549d07be3abca49a6e641b3b36ca356c53ae
[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 <stdio.h>
18 #include <stdlib.h>
19
20 #include "filters.h"
21
22 static __inline__ void flipVertical(char * source, int srcWidth, int srcHeight, char * destination,
23         int dstWidth __unused, int dstHeight __unused) {
24     //Vertical
25     size_t cpy_bytes = sizeof(char) * 4;
26     int width = cpy_bytes * srcWidth;
27     int length = srcHeight;
28     int total = length * width;
29     size_t bytes_to_copy = sizeof(char) * width;
30     int i = 0;
31     int temp = total - width;
32     for (i = 0; i < total; i += width) {
33         memcpy(destination + temp - i, source + i, bytes_to_copy);
34     }
35 }
36
37 static __inline__ void flipHorizontal(char * source, int srcWidth, int srcHeight,
38         char * destination, int dstWidth __unused, int dstHeight __unused) {
39     //Horizontal
40     size_t cpy_bytes = sizeof(char) * 4;
41     int width = cpy_bytes * srcWidth;
42     int length = srcHeight;
43     int total = length * width;
44     int i = 0;
45     int j = 0;
46     int temp = 0;
47     for (i = 0; i < total; i+= width) {
48         temp = width + i - cpy_bytes;
49         for (j = 0; j < width; j+=cpy_bytes) {
50             memcpy(destination + temp - j, source + i + j, cpy_bytes);
51         }
52     }
53 }
54
55 static __inline__ void flip_fun(int flip, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
56     int horiz = (flip & 1) != 0;
57     int vert = (flip & 2) != 0;
58     if (horiz && vert){
59         int arr_len = dstWidth * dstHeight * sizeof(char) * 4;
60         char* temp = (char *) malloc(arr_len);
61         flipHorizontal(source, srcWidth, srcHeight, temp, dstWidth, dstHeight);
62         flipVertical(temp, dstWidth, dstHeight, destination, dstWidth, dstHeight);
63         free(temp);
64         return;
65     }
66     if (horiz){
67         flipHorizontal(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
68         return;
69     }
70     if (vert){
71         flipVertical(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
72         return;
73     }
74 }
75
76 //90 CCW (opposite of what's used in UI?)
77 static __inline__ void rotate90(char * source, int srcWidth, int srcHeight, char * destination,
78         int dstWidth __unused, int dstHeight __unused) {
79     size_t cpy_bytes = sizeof(char) * 4;
80     int width = cpy_bytes * srcWidth;
81     int length = srcHeight;
82     for (size_t j = 0; j < length * cpy_bytes; j+= cpy_bytes){
83         for (int i = 0; i < width; i+=cpy_bytes){
84             int column_disp = (width - cpy_bytes - i) * length;
85             int row_disp = j;
86             memcpy(destination + column_disp + row_disp , source + j * srcWidth + i, cpy_bytes);
87         }
88     }
89 }
90
91 static __inline__ void rotate180(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
92     flip_fun(3, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
93 }
94
95 static __inline__ void rotate270(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
96     rotate90(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
97     flip_fun(3, destination, dstWidth, dstHeight, destination, dstWidth, dstHeight);
98 }
99
100 // rotate == 1 is 90 degrees, 2 is 180, 3 is 270 (positive is CCW).
101 static __inline__ void rotate_fun(int rotate, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
102     switch( rotate )
103     {
104         case 1:
105             rotate90(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
106             break;
107         case 2:
108             rotate180(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
109             break;
110         case 3:
111             rotate270(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
112             break;
113         default:
114             break;
115     }
116 }
117
118 static __inline__ void crop(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight, int offsetWidth, int offsetHeight){
119     size_t cpy_bytes = sizeof(char) * 4;
120     int row_width = cpy_bytes * srcWidth;
121     int new_row_width = cpy_bytes * dstWidth;
122     if ((srcWidth > dstWidth + offsetWidth) || (srcHeight > dstHeight + offsetHeight)){
123         return;
124     }
125     int j = 0;
126     for (j = offsetHeight; j < offsetHeight + dstHeight; j++){
127         memcpy(destination + (j - offsetHeight) * new_row_width, source + j * row_width + offsetWidth * cpy_bytes, cpy_bytes * dstWidth );
128     }
129 }
130
131 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterFlip, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint flip) {
132     char* destination = 0;
133     char* source = 0;
134     if (srcWidth != dstWidth || srcHeight != dstHeight) {
135         return;
136     }
137     AndroidBitmap_lockPixels(env, src, (void**) &source);
138     AndroidBitmap_lockPixels(env, dst, (void**) &destination);
139     flip_fun(flip, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
140     AndroidBitmap_unlockPixels(env, dst);
141     AndroidBitmap_unlockPixels(env, src);
142 }
143
144 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterRotate, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint rotate) {
145     char* destination = 0;
146     char* source = 0;
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     AndroidBitmap_lockPixels(env, src, (void**) &source);
158     AndroidBitmap_lockPixels(env, dst, (void**) &destination);
159     crop(source, srcWidth, srcHeight, destination, dstWidth, dstHeight, offsetWidth, offsetHeight);
160     AndroidBitmap_unlockPixels(env, dst);
161     AndroidBitmap_unlockPixels(env, src);
162 }
163
164 void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jint srcWidth __unused,
165         jint srcHeight __unused, jobject dst, jint dstWidth, jint dstHeight,
166         jfloat straightenAngle __unused) {
167     char* destination = 0;
168     char* source = 0;
169     int len = dstWidth * dstHeight * 4;
170     AndroidBitmap_lockPixels(env, src, (void**) &source);
171     AndroidBitmap_lockPixels(env, dst, (void**) &destination);
172     // TODO: implement straighten
173     int i = 0;
174     for (; i < len; i += 4) {
175         destination[RED] = 128;
176         destination[GREEN] = source[GREEN];
177         destination[BLUE] = 128;
178     }
179     AndroidBitmap_unlockPixels(env, dst);
180     AndroidBitmap_unlockPixels(env, src);
181 }
182