Loading jni/filters/geometry.c +116 −32 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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); } Loading @@ -98,3 +181,4 @@ void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jin AndroidBitmap_unlockPixels(env, dst); AndroidBitmap_unlockPixels(env, src); } src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java +14 −5 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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); Loading Loading @@ -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; Loading Loading
jni/filters/geometry.c +116 −32 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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); } Loading @@ -98,3 +181,4 @@ void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jin AndroidBitmap_unlockPixels(env, dst); AndroidBitmap_unlockPixels(env, src); }
src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java +14 −5 Original line number Diff line number Diff line Loading @@ -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"; Loading @@ -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); Loading Loading @@ -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; Loading