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 <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 
    183