Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd14e827 authored by Ruben Brunk's avatar Ruben Brunk Committed by Android (Google) Code Review
Browse files

Merge "Implementing Geometry save operations." into gb-ub-photos-arches

parents d490f1aa 18fc4c1c
Loading
Loading
Loading
Loading
+116 −32
Original line number Diff line number Diff line
@@ -15,46 +15,138 @@
 */

#include "filters.h"
#include <stdio.h>

__inline__ void flipVertical(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    //Vertical
    size_t cpy_bytes = sizeof(char) * 4;
    int width = cpy_bytes * srcWidth;
    int length = srcHeight;
    int total = length * width;
    size_t bytes_to_copy = sizeof(char) * width;
    int i = 0;
    int temp = total - width;
    for (i = 0; i < total; i += width) {
        memcpy(destination + temp - i, source + i, bytes_to_copy);
    }
}

__inline__ void flipHorizontal(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    //Horizontal
    size_t cpy_bytes = sizeof(char) * 4;
    int width = cpy_bytes * srcWidth;
    int length = srcHeight;
    int total = length * width;
    int i = 0;
    int j = 0;
    int temp = 0;
    for (i = 0; i < total; i+= width) {
        temp = width + i - cpy_bytes;
        for (j = 0; j < width; j+=cpy_bytes) {
            memcpy(destination + temp - j, source + i + j, cpy_bytes);
        }
    }
}

__inline__ void flip_fun(int flip, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    int horiz = (flip & 1) != 0;
    int vert = (flip & 2) != 0;
    if (horiz && vert){
        int arr_len = dstWidth * dstHeight * sizeof(char) * 4;
        char* temp = (char *) malloc(arr_len);
        flipHorizontal(source, srcWidth, srcHeight, temp, dstWidth, dstHeight);
        flipVertical(temp, dstWidth, dstHeight, destination, dstWidth, dstHeight);
        free(temp);
        return;
    }
    if (horiz){
        flipHorizontal(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
        return;
    }
    if (vert){
        flipVertical(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
        return;
    }
}

//90 CCW (opposite of what's used in UI?)
__inline__ void rotate90(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    size_t cpy_bytes = sizeof(char) * 4;
    int width = cpy_bytes * srcWidth;
    int length = srcHeight;
    int total = length * width;
    int i = 0;
    int j = 0;
    for (j = 0; j < length * cpy_bytes; j+= cpy_bytes){
        for (i = 0; i < width; i+=cpy_bytes){
            int column_disp = (width - cpy_bytes - i) * length;
            int row_disp = j;
            memcpy(destination + column_disp + row_disp , source + j * srcWidth + i, cpy_bytes);
        }
    }
}

__inline__ void rotate180(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    flip_fun(3, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
}

__inline__ void rotate270(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    rotate90(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
    flip_fun(3, destination, dstWidth, dstHeight, destination, dstWidth, dstHeight);
}

// rotate == 1 is 90 degrees, 2 is 180, 3 is 270 (positive is CCW).
__inline__ void rotate_fun(int rotate, char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight){
    switch( rotate )
    {
        case 1:
            rotate90(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
            break;
        case 2:
            rotate180(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
            break;
        case 3:
            rotate270(source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
            break;
        default:
            break;
    }
}

__inline__ void crop(char * source, int srcWidth, int srcHeight, char * destination, int dstWidth, int dstHeight, int offsetWidth, int offsetHeight){
    size_t cpy_bytes = sizeof(char) * 4;
    int row_width = cpy_bytes * srcWidth;
    int new_row_width = cpy_bytes * dstWidth;
    if ((srcWidth > dstWidth + offsetWidth) || (srcHeight > dstHeight + offsetHeight)){
        return;
    }
    int i = 0;
    int j = 0;
    for (j = offsetHeight; j < offsetHeight + dstHeight; j++){
        memcpy(destination + (j - offsetHeight) * new_row_width, source + j * row_width + offsetWidth * cpy_bytes, cpy_bytes * dstWidth );
    }
}

void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterFlip, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint flip) {
    char* destination = 0;
    char* source = 0;
    int len = dstWidth * dstHeight * 4;
    if (srcWidth != dstWidth || srcHeight != dstHeight) {
        return;
    }
    AndroidBitmap_lockPixels(env, src, (void**) &source);
    AndroidBitmap_lockPixels(env, dst, (void**) &destination);
    int i = 0;
    for (; i < len; i += 4) {
        int r = source[RED];
        int g = source[GREEN];
        int b = source[BLUE];
        // TODO: implement flip
        destination[RED] = 255;
        destination[GREEN] = g;
        destination[BLUE] = b;
    }
    flip_fun(flip, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
    AndroidBitmap_unlockPixels(env, dst);
    AndroidBitmap_unlockPixels(env, src);
}

void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterRotate, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jfloat rotate) {
void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterRotate, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint rotate) {
    char* destination = 0;
    char* source = 0;
    int len = dstWidth * dstHeight * 4;
    AndroidBitmap_lockPixels(env, src, (void**) &source);
    AndroidBitmap_lockPixels(env, dst, (void**) &destination);
    // TODO: implement rotate
    int i = 0;
    for (; i < len; i += 4) {
        int r = source[RED];
        int g = source[GREEN];
        int b = source[BLUE];
        destination[RED] = r;
        destination[GREEN] = 255;
        destination[BLUE] = b;
    }
    rotate_fun(rotate, source, srcWidth, srcHeight, destination, dstWidth, dstHeight);
    AndroidBitmap_unlockPixels(env, dst);
    AndroidBitmap_unlockPixels(env, src);
}
@@ -65,16 +157,7 @@ void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterCrop, jobject src, jint srcW
    int len = dstWidth * dstHeight * 4;
    AndroidBitmap_lockPixels(env, src, (void**) &source);
    AndroidBitmap_lockPixels(env, dst, (void**) &destination);
    // TODO: implement crop
    int i = 0;
    for (; i < len; i += 4) {
        int r = source[RED];
        int g = source[GREEN];
        int b = source[BLUE];
        destination[RED] = r;
        destination[GREEN] = g;
        destination[BLUE] = 255;
    }
    crop(source, srcWidth, srcHeight, destination, dstWidth, dstHeight, offsetWidth, offsetHeight);
    AndroidBitmap_unlockPixels(env, dst);
    AndroidBitmap_unlockPixels(env, src);
}
@@ -98,3 +181,4 @@ void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jin
    AndroidBitmap_unlockPixels(env, dst);
    AndroidBitmap_unlockPixels(env, src);
}
+14 −5
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ public class ImageFilterGeometry extends ImageFilter {
    private static final int BOTH = 3;
    private static final int VERTICAL = 2;
    private static final int HORIZONTAL = 1;
    private static final int NINETY = 1;
    private static final int ONE_EIGHTY = 2;
    private static final int TWO_SEVENTY = 3;

    public ImageFilterGeometry() {
        mName = "Geometry";
@@ -54,7 +57,7 @@ public class ImageFilterGeometry extends ImageFilter {
            Bitmap dst, int dstWidth, int dstHeight, int flip);

    native protected void nativeApplyFilterRotate(Bitmap src, int srcWidth, int srcHeight,
            Bitmap dst, int dstWidth, int dstHeight, float rotate);
            Bitmap dst, int dstWidth, int dstHeight, int rotate);

    native protected void nativeApplyFilterCrop(Bitmap src, int srcWidth, int srcHeight,
            Bitmap dst, int dstWidth, int dstHeight, int offsetWidth, int offsetHeight);
@@ -111,15 +114,21 @@ public class ImageFilterGeometry extends ImageFilter {
        if (rotate) {
            // Fails for non-90 degree rotations
            Bitmap modBitmapRotate = null;
            if (((int) (sAngle / 90)) % 2 == 0) {
            rAngle %= 360;
            int deg = (int) (rAngle / 90);
            deg = -deg;  // Make CCW positive
            if (deg < 0)
                deg += 4;
            // Now deg is in [1, 3] as required by native rotate
            if (deg == ONE_EIGHTY) {
                modBitmapRotate = Bitmap.createBitmap(bmWidth, bmHeight, mConfig);
                nativeApplyFilterRotate(modBitmap, bmWidth, bmHeight, modBitmapRotate,
                        bmWidth, bmHeight, mGeometry.getRotation());
                        bmWidth, bmHeight, deg);
                modifiedBounds = new Rect(0, 0, bmWidth, bmHeight);
            } else {
            } else if (deg == TWO_SEVENTY || deg == NINETY) {
                modBitmapRotate = Bitmap.createBitmap(bmHeight, bmWidth, mConfig);
                nativeApplyFilterRotate(modBitmap, bmWidth, bmHeight, modBitmapRotate,
                        bmHeight, bmWidth, mGeometry.getRotation());
                        bmHeight, bmWidth, deg);
                modifiedBounds = new Rect(0, 0, bmHeight, bmWidth);
            }
            modBitmap = modBitmapRotate;