Home | History | Annotate | Download | only in filters
      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 
    185